bytebase/bytebase · error
type %q: expected TypeCast, got %T
Error message
type %q: expected TypeCast, got %T
What it means
The ResTarget's value must be an *ast.TypeCast (the NULL::<type> cast) for typeNameFromString to extract the ast.TypeName. This error fires when the expression inside the sole target is not a cast, meaning the type string caused the probe query to parse into some other expression form. It is the last shape check before returning the TypeName, guarding the entire cast-extraction trick.
Source
Thrown at backend/plugin/parser/pg/query_span_loader_type_name.go:48
return nil, errors.Wrapf(err, "parse type %q", typeStr)
}
if len(stmts) != 1 {
return nil, errors.Errorf("type %q: expected 1 statement, got %d", typeStr, len(stmts))
}
sel, ok := stmts[0].AST.(*ast.SelectStmt)
if !ok {
return nil, errors.Errorf("type %q: expected SelectStmt, got %T", typeStr, stmts[0].AST)
}
if sel.TargetList == nil || len(sel.TargetList.Items) != 1 {
return nil, errors.Errorf("type %q: expected 1 target", typeStr)
}
rt, ok := sel.TargetList.Items[0].(*ast.ResTarget)
if !ok {
return nil, errors.Errorf("type %q: expected ResTarget, got %T", typeStr, sel.TargetList.Items[0])
}
cast, ok := rt.Val.(*ast.TypeCast)
if !ok {
return nil, errors.Errorf("type %q: expected TypeCast, got %T", typeStr, rt.Val)
}
return cast.TypeName, nil
}
// extractUserTypeRefs returns the user-defined type references embedded in a
// PG type string. Built-in types, PG internal array forms (_name), and
// system-schema-qualified types return nil.
//
// Soundness rule (hard contract C5): false negatives are acceptable (the
// loader's pseudo fallback catches them); false positives are not, because
// they invent edges in the dependency graph.
func extractUserTypeRefs(typeStr string) []UserTypeRef {
if typeStr == "" {
return nil
}
base := stripTypeModifiers(typeStr)
if base == "" || isBuiltinType(base) {
return nilView on GitHub (pinned to 1870550677)
Solutions
- Inspect the %T value in the error to see which expression node replaced the TypeCast
- Normalize or reject the offending type string before it enters the loader
- Extend the extractor to also unwrap the new node form if it legitimately encodes a type
- Add the failing string to TestLoaderTypeNameFromString to verify the fix
Defensive patterns
Strategy: try-catch
Try / catch
if _, err := typeNameFromString(typeStr); err != nil {
return fmt.Errorf("unsupported type syntax %q: %w", typeStr, err)
} Prevention
- Test exotic type strings (arrays, interval qualifiers, schemanified types) against the loader
- Reject or normalize non-cast-producing syntax at the metadata ingestion boundary
- Extend the extractor for new expression node forms instead of letting them fail at runtime
When it happens
Trigger: rt.Val is not *ast.TypeCast — e.g. a type string containing operators or syntax that turns NULL::X into a different expression (such as a function call or A_Expr) — reached via buildCompositeTypeStmt, buildCreateStmt, buildCreateFunctionStmtFromSignature, or mustTypeName.
Common situations: Type strings with unusual syntax (e.g. interval qualifiers, array bounds expressions, or typos like "int[]" variants) that the PG parser rewrites into non-cast nodes; also parser version changes in node representation.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- type %q: expected 1 statement, got %d
- type %q: expected SelectStmt, got %T
- type %q: expected 1 target
- type %q: expected ResTarget, got %T
- database name not found
AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06).
Data as JSON: /api/errors/ab32ed0f9aa67e4d.
Report an issue: GitHub.