multica-ai/multica · error

empty component in %q

Error message

empty component in %q

What it means

quoteQualifiedIdentifier splits on "." and rejects any empty component, catching degenerate names like "issues.", ".issues", or "." that would otherwise sanitize to an empty quoted component ("issues".""), which is invalid or points nowhere.

Source

Thrown at server/cmd/migrate/main.go:479

// 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)

Solutions

  1. Print/inspect the offending value (the %q in the message shows it exactly) and fix the empty side.
  2. Require both schema and table at the source — validate flags/config before composing the name.
  3. If schema is optional, only prefix the dot when the schema part is non-empty.

Example fix

// before
name := fmt.Sprintf("%s.%s", schema, table) // schema == "" -> ".issues"

// after
var name string
if schema != "" {
    name = schema + "." + table
} else {
    name = table
}
Defensive patterns

Strategy: validation

Validate before calling

func joinTable(schema, table string) (string, error) {
    if table == "" {
        return "", fmt.Errorf("table component is required")
    }
    if schema == "" {
        return table, nil
    }
    return schema + "." + table, nil
}

Type guard

func hasNoEmptyComponent(name string) bool {
    for _, p := range strings.Split(name, ".") {
        if p == "" {
            return false
        }
    }
    return true
}

Try / catch

q, err := quoteQualifiedIdentifier(name)
if err != nil {
    return fmt.Errorf("bad identifier %q (empty component): %w", name, err)
}

Prevention

When it happens

Trigger: Passing a name with a leading/trailing dot or a bare dot: "schema.", ".table", ".", or strings produced by joining empty parts with dots.

Common situations: fmt.Sprintf("%s.%s", schema, table) with one variable empty; config values written as "workspace." with a trailing dot; strings.Split output reassembled without filtering empties.

Related errors


AI-assisted analysis of multica-ai/multica@2c0912b6ec (2026-08-15). Data as JSON: /api/errors/2bd3098be5932340. Report an issue: GitHub.