pocketbase/pocketbase · error

[strftime] failed to resolve time-value argument: %w

Error message

[strftime] failed to resolve time-value argument: %w

What it means

Wrapped error from `strftime` when its optional second (time-value) argument fails resolution. The time-value may be a text literal, number, or field identifier; if the field resolver rejects an identifier argument (field not allowlisted/resolvable), this error wraps the underlying cause such as `failed to resolve field %q`.

Source

Thrown at tools/search/token_functions.go:120

		}

		// no further arguments
		if totalArgs == 1 {
			formatArgResult.NullFallback = NullFallbackEnforced
			formatArgResult.Identifier = "strftime(" + formatArgResult.Identifier + ")"
			return formatArgResult, nil
		}

		// time-value arg
		// -----------------------------------------------------------
		allowedTimeValueTokens := []fexpr.TokenType{fexpr.TokenText, fexpr.TokenIdentifier, fexpr.TokenNumber}
		if !slices.Contains(allowedTimeValueTokens, args[1].Type) {
			return nil, errors.New("[strftime] expects the second argument to be of a valid time-value type")
		}

		timeValueArgResult, err := argTokenResolverFunc(args[1])
		if err != nil {
			return nil, fmt.Errorf("[strftime] failed to resolve time-value argument: %w", err)
		}

		// modifiers args
		// -----------------------------------------------------------
		resolvedModifierArgs := make([]*ResolverResult, totalArgs-2)
		for i, arg := range args[2:] {
			if arg.Type != fexpr.TokenText {
				return nil, fmt.Errorf("[strftime] invalid modifier argument %d - can be only string", i)
			}

			resolved, err := argTokenResolverFunc(arg)
			if err != nil {
				return nil, fmt.Errorf("[strftime] failed to resolve modifier argument %d: %w", i, err)
			}

			resolvedModifierArgs[i] = resolved
		}

View on GitHub (pinned to 5d217ddb50)

Solutions

  1. Add the referenced time field to the resolver's allowed fields
  2. Fix the field name/path spelling against the collection schema
  3. Check the wrapped error cause to identify the exact failing identifier
  4. Pass an explicit time literal instead of a field if the field is not meant to be filterable

Example fix

// before
resolver := search.NewSimpleFieldResolver("id")
// filter: strftime('%Y', created) = '2026'
// after
resolver := search.NewSimpleFieldResolver("id", "created")
Defensive patterns

Strategy: validation

Validate before calling

// pre-check the time-value field is resolvable
if strings.HasPrefix(timeValueArg, "'") == false && !isNumber(timeValueArg) {
    if _, err := resolver.Resolve(timeValueArg); err != nil {
        return fmt.Errorf("strftime time-value %q not allowed: %w", timeValueArg, err)
    }
}

Type guard

null

Try / catch

if err != nil && strings.Contains(err.Error(), "[strftime] failed to resolve time-value") {
    return apiError400("unknown time-value field in strftime: check field name and allowlist")
}

Prevention

When it happens

Trigger: `strftime('%Y', someField) = '2026'` where `someField` is not in the resolver's allowed fields, or a dotted/JSON path that the resolver cannot resolve.

Common situations: Formatting a date field that was never added to the search field allowlist; typos in the field name; referencing relation fields without allowing the dotted path; schema renames not propagated to filter strings.

Related errors


AI-assisted analysis of pocketbase/pocketbase@5d217ddb50 (2026-08-15). Data as JSON: /api/errors/3a484d699a02fb8a. Report an issue: GitHub.