multica-ai/multica · error
empty identifier
Error message
empty identifier
What it means
quoteQualifiedIdentifier rejects an empty string before building a quoted SQL identifier. Because Postgres cannot take identifiers as query parameters, the function interpolates them via pgx.Identifier.Sanitize, and an empty name would otherwise interpolate to an empty (invalid) reference.
Solutions
- Trace where the name originates (flag/config) and require it explicitly before calling.
- Add a non-empty default or fail fast at flag-parsing time with an actionable message.
- Sanitize lists by filtering out empty elements before iterating.
Example fix
// before
q, err := quoteQualifiedIdentifier(tableName)
// after
if strings.TrimSpace(tableName) == "" {
return fmt.Errorf("--table is required")
}
q, err := quoteQualifiedIdentifier(strings.TrimSpace(tableName)) Defensive patterns
Strategy: validation
Validate before calling
func safeIdentifier(name string) (string, error) {
name = strings.TrimSpace(name)
if name == "" {
return "", fmt.Errorf("table name is required")
}
return quoteQualifiedIdentifier(name)
} Type guard
func isValidIdentifierName(name string) bool {
if name == "" {
return false
}
for _, p := range strings.Split(name, ".") {
if p == "" {
return false
}
}
return len(strings.Split(name, ".")) <= 2
} Try / catch
q, err := quoteQualifiedIdentifier(name)
if err != nil {
return fmt.Errorf("invalid table %q from config: %w", name, err)
} Prevention
- Validate non-empty at flag/config parse time with a message naming the flag or key.
- Filter empty elements when building identifier lists from splits/joins.
- Never pass user input straight through; route everything through quoteQualifiedIdentifier.
When it happens
Trigger: Calling quoteQualifiedIdentifier("") — typically because a table name came from a flag, env var, or config value that was never set or was trimmed to empty.
Common situations: A CLI flag like --table left blank; a config key read with a default of ""; a loop over a list where one element is an empty string after splitting on a delimiter.
Related errors
- empty component in
- identifier has more than one dot; only schema.table is…
- agent_timeout must be >= 0
- agent_timeout must be a Go duration (e.g. 10m, 0s to…
- --app-url is required when --server-url points at a remote…
AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15).
Data as JSON: /api/errors/20ce612def523deb.
Report an issue: GitHub.
Appendix: source
Thrown at server/cmd/migrate/main.go:471
fmt.Printf(" %s %s\n", opts.Direction, version)
}
return nil
}
// quoteQualifiedIdentifier safely quotes either an unqualified table
// name ("foo") or a schema-qualified name ("schema.foo") for embedding
// into a SQL statement. Postgres does not let parametrized queries
// supply identifiers, so we have to interpolate, but pgx.Identifier
// does the right escaping (double-quotes, embedded-quote handling).
//
// The accepted shape is exactly one or two dot-separated components.
// Names containing more than one dot are rejected outright rather than
// silently sanitized into a "schema"."b.c" reference, which is valid
// SQL but almost certainly not what the caller meant.
func quoteQualifiedIdentifier(name string) (string, error) {
if name == "" {
return "", fmt.Errorf("empty identifier")
}
parts := strings.Split(name, ".")
if len(parts) > 2 {
return "", fmt.Errorf("identifier %q has more than one dot; only schema.table is supported", name)
}
for _, p := range parts {
if p == "" {
return "", fmt.Errorf("empty component in %q", name)
}
}
return pgx.Identifier(parts).Sanitize(), nil
}
View on GitHub (pinned to 2c0912b6ec)