usememos/memos · error

expression is not a literal

Error message

expression is not a literal

What it means

getConstValue requires the expression to be a constant literal (exprv1.Expr_ConstExpr) and unwraps string, int, uint, double, and bool kinds. Any non-literal — identifier, call, list — fails here; it typically surfaces wrapped as 'only supports literal arguments' from contains/matches/timestamp/duration validators.

Source

Thrown at internal/filter/parser.go:468

		return CompareLte, nil
	case "_>=_":
		return CompareGte, nil
	default:
		return "", errors.Errorf("unsupported comparison operator %q", fn)
	}
}

func getIdentName(expr *exprv1.Expr) (string, error) {
	if ident := expr.GetIdentExpr(); ident != nil {
		return ident.GetName(), nil
	}
	return "", errors.New("expression is not an identifier")
}

func getConstValue(expr *exprv1.Expr) (interface{}, error) {
	v, ok := expr.ExprKind.(*exprv1.Expr_ConstExpr)
	if !ok {
		return nil, errors.New("expression is not a literal")
	}
	switch x := v.ConstExpr.ConstantKind.(type) {
	case *exprv1.Constant_StringValue:
		return v.ConstExpr.GetStringValue(), nil
	case *exprv1.Constant_Int64Value:
		return v.ConstExpr.GetInt64Value(), nil
	case *exprv1.Constant_Uint64Value:
		return int64(v.ConstExpr.GetUint64Value()), nil
	case *exprv1.Constant_DoubleValue:
		return v.ConstExpr.GetDoubleValue(), nil
	case *exprv1.Constant_BoolValue:
		return v.ConstExpr.GetBoolValue(), nil
	case *exprv1.Constant_NullValue:
		return nil, nil
	default:
		return nil, errors.Errorf("unsupported constant %T", x)
	}
}

View on GitHub (pinned to 14d757ce1f)

Solutions

  1. Replace the argument with a literal constant
  2. For field-to-field comparison use the == operator directly, not a function argument
  3. Fold arithmetic yourself and inline the resulting number/string

Example fix

// before
content.contains(tag)

// after
content.contains("work")
Defensive patterns

Strategy: type-guard

Validate before calling

// Go (AST level): only pass ConstExpr nodes where literals are required
if arg.GetConstExpr() == nil {
    return errors.New("argument must be a constant literal")
}

Type guard

func isLiteral(e *exprv1.Expr) bool { return e.GetConstExpr() != nil }

Prevention

When it happens

Trigger: content.contains(tag) (identifier argument), timestamp(created_ts) (field argument), or duration(30 * 24) where the argument is an expression rather than a single literal.

Common situations: Trying to compare two fields via a function argument, or passing computed values where the DSL only accepts literals — the filter compiler intentionally forbids non-constant arguments so predicates can be compiled to SQL.

Related errors


AI-assisted analysis of usememos/memos@14d757ce1f (2026-08-15). Data as JSON: /api/errors/031fff511b662fe3. Report an issue: GitHub.