gofr-dev/gofr · warning
%w: %s
Error message
%w: %s
What it means
In the DynamoDB KV client, Get wraps errKeyNotFound with the offending key using fmt.Errorf("%w: %s", errKeyNotFound, key) when the item exists but has no 'value' attribute, or more broadly when the key is absent. Because %w is used, errors.Is(err, errKeyNotFound) still matches. The message form is 'key not found: <key>'.
Source
Thrown at pkg/gofr/datasource/kv-store/dynamodb/dynamo.go:174
out, err := c.db.GetItem(ctx, input)
if err != nil {
c.logger.Errorf("error while fetching data for key: %v, error: %v", key, err)
return "", err
}
if out.Item == nil {
return "", errKeyNotFound
}
// Look for a "value" field that contains the JSON string
if valueField, exists := out.Item["value"]; exists {
if stringValue, ok := valueField.(*types.AttributeValueMemberS); ok {
return stringValue.Value, nil
}
}
// If no "value" field exists, return key not found error
return "", fmt.Errorf("%w: %s", errKeyNotFound, key)
}
func (c *Client) Set(ctx context.Context, key, value string) error {
if !c.connected {
return errClientNotConnected
}
span := c.addTrace(ctx, "set", key)
defer c.sendOperationsStats(time.Now(), "SET", "set", span, key)
// Store the value as a string in the "value" field
item := map[string]types.AttributeValue{
c.configs.PartitionKeyName: &types.AttributeValueMemberS{Value: key},
"value": &types.AttributeValueMemberS{Value: value},
}
input := &dynamodb.PutItemInput{
TableName: aws.String(c.configs.Table),View on GitHub (pinned to 187eb24962)
Solutions
- Check errors.Is(err, errKeyNotFound) and treat as a miss rather than a hard failure
- Ensure writers use this client's Set so items contain the 'value' attribute
- Verify Configs.Table targets the intended table
- Inspect the key echoed in the message for typos/casing mismatches
Example fix
// before
v, err := store.Get(ctx, k)
if err != nil { log.Fatal(err) }
// after
v, err := store.Get(ctx, k)
if errors.Is(err, dynamodb.ErrKeyNotFound) { v, err = loadDefault(k), nil } Defensive patterns
Strategy: type-guard
Validate before calling
// check key before calling Get
if key == "" { return errors.New("empty key") }
// ensure writers use Set so items carry the 'value' attribute Type guard
func IsKeyNotFound(err error) bool { return errors.Is(err, dynamodb.ErrKeyNotFound) } Try / catch
v, err := store.Get(ctx, key)
if errors.Is(err, dynamodb.ErrKeyNotFound) {
log.Printf("miss: %s", key) // message contains key
return handleMiss(key)
}
if err != nil { return err } Prevention
- Use errors.Is, never string matching, on the wrapped sentinel
- Ensure all table writers use this client's Set (uniform 'value' attribute)
- Validate key format with a regex/helper before Get
- Confirm table selection in configuration tests
When it happens
Trigger: Client.Get on a key whose DynamoDB item lacks a 'value' attribute (e.g. items written by other tools or with different attribute names), or on keys that do not exist in the table.
Common situations: Table populated by another application or migration using different attribute names, partially written items, wrong table selected, keys deleted concurrently.
Related errors
- key not found
- client not connected, call Connect() first
- status down
- failed to marshal value to JSON: %w
- failed to unmarshal JSON: %w
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/ba6d4f7e3ba9182d.
Report an issue: GitHub.