{"record":{"id":"c858a6ae95fbbcd5","repo":"googleapis/mcp-toolbox","slug":"unable-to-get-column-names-w","errorCode":null,"errorMessage":"unable to get column names: %w","messagePattern":"unable to get column names: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/sources/sqlite/sqlite.go","lineNumber":115,"sourceCode":"}\n\nfunc (s *Source) SQLiteDB() *sql.DB {\n\treturn s.Db\n}\n\nfunc (s *Source) RunSQL(ctx context.Context, statement string, params []any) (any, error) {\n\t// Execute the SQL query with parameters\n\tstatement = sqlcommenter.PrependComment(ctx, statement, SourceType, s.SQLCommenter)\n\trows, err := s.SQLiteDB().QueryContext(ctx, statement, params...)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to execute query: %w\", err)\n\t}\n\tdefer rows.Close()\n\n\t// Get column names\n\tcols, err := rows.Columns()\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"unable to get column names: %w\", err)\n\t}\n\n\t// The sqlite driver does not support ColumnTypes, so we can't get the\n\t// underlying database type of the columns. We'll have to rely on the\n\t// generic `any` type and then handle the JSON data separately.\n\trawValues := make([]any, len(cols))\n\tvalues := make([]any, len(cols))\n\tfor i := range rawValues {\n\t\tvalues[i] = &rawValues[i]\n\t}\n\n\t// Prepare the result slice\n\tout := []any{}\n\tfor rows.Next() {\n\t\tif err := rows.Scan(values...); err != nil {\n\t\t\treturn nil, fmt.Errorf(\"unable to scan row: %w\", err)\n\t\t}\n","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/googleapis/mcp-toolbox/blob/8cc6e09de2ad7b8bffc77751799585a1401a48eb/internal/sources/sqlite/sqlite.go#L97-L133","documentation":"sqlite RunSQL (internal/sources/sqlite/sqlite.go:115) calls rows.Columns() to retrieve result column names after a successful query. If the rows handle has already been invalidated (connection closed, driver error) the call fails and is wrapped as \"unable to get column names\". This is rare because the query itself already succeeded.","triggerScenarios":"RunSQL where rows.Columns() fails after QueryContext succeeded — typically a driver-level connection failure occurring between query execution and metadata retrieval, or context cancellation in between.","commonSituations":"Context deadline hit right after query start; underlying connection dropped (unusual for in-process SQLite, more plausible with a networked driver); driver bug.","solutions":["Increase the context/request timeout if deadlines are tight","Retry the query — this is usually transient","Check for connection drops if using a non-local sqlite driver (e.g. a proxy/turso-style backend)","If reproducible, file an issue with the sqlite driver in use"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"res, err := source.RunSQL(ctx, stmt, params)\nif err != nil && strings.Contains(err.Error(), \"unable to get column names\") {\n\t// transient: retry once with backoff\n\tres, err = source.RunSQL(ctx, stmt, params)\n}","preventionTips":["Use generous context timeouts for query calls","Retry transient metadata failures once","Keep the sqlite driver up to date"],"tags":["sqlite","rows-metadata"],"backgroundTag":"database-query-failed","analyzedSha":"8cc6e09de2ad7b8bffc77751799585a1401a48eb","analyzedAt":"2026-09-05T01:10:36.887Z","contentChangedAt":"2026-09-05T01:10:36.887Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}