{"record":{"id":"fda95b201de3bd2f","repo":"benbjohnson/litestream","slug":"unsupported-file-control-op-d","errorCode":null,"errorMessage":"unsupported file control op: %d","messagePattern":"unsupported file control op: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"vfs.go","lineNumber":2429,"sourceCode":"\tcfg := &dateparser.Configuration{\n\t\tCurrentTime: time.Now().UTC(),\n\t}\n\tresult, err := dateparser.Parse(cfg, value)\n\tif err != nil {\n\t\treturn time.Time{}, fmt.Errorf(\"invalid timestamp (expected RFC3339 or relative time like '5 minutes ago'): %s\", value)\n\t}\n\tif result.Time.IsZero() {\n\t\treturn time.Time{}, fmt.Errorf(\"could not parse time: %s\", value)\n\t}\n\treturn result.Time.UTC(), nil\n}\n\n// FileControl handles file control operations, specifically PRAGMA commands for time travel.\nfunc (f *VFSFile) FileControl(op int, pragmaName string, pragmaValue *string) (*string, error) {\n\tconst SQLITE_FCNTL_PRAGMA = 14\n\n\tif op != SQLITE_FCNTL_PRAGMA {\n\t\treturn nil, fmt.Errorf(\"unsupported file control op: %d\", op)\n\t}\n\n\tname := strings.ToLower(pragmaName)\n\n\tf.logger.Debug(\"file control\", \"pragma\", name, \"value\", pragmaValue)\n\n\tswitch name {\n\tcase \"litestream_txid\":\n\t\tif pragmaValue != nil {\n\t\t\treturn nil, fmt.Errorf(\"litestream_txid is read-only\")\n\t\t}\n\t\ttxid := f.Pos().TXID\n\t\tresult := txid.String()\n\t\treturn &result, nil\n\n\tcase \"litestream_lag\":\n\t\tif pragmaValue != nil {\n\t\t\treturn nil, fmt.Errorf(\"litestream_lag is read-only\")","sourceCodeStart":2411,"sourceCodeEnd":2447,"githubUrl":"https://github.com/benbjohnson/litestream/blob/4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3/vfs.go#L2411-L2447","documentation":"VFSFile.FileControl() in vfs.go was invoked with a file-control opcode other than SQLITE_FCNTL_PRAGMA (14). FileControl in this VFS only implements PRAGMA dispatch; any other xFileControl op (e.g. other SQLITE_FCNTL_* codes SQLite probes for) is rejected with this error instead of returning a graceful not-supported signal.","triggerScenarios":"SQLite core or an extension issues an xFileControl call with an opcode other than 14 against the litestream VFS file — typically during database open/feature probing, WAL mode negotiation, or when an extension requests an fcntl the VFS does not implement.","commonSituations":"Happens during normal SQLite operation when the core probes for optional file-control features; also seen when drivers or tools issue non-PRAGMA file controls directly. Developers debugging 'unsupported file control op' usually assumed all fcntl ops were handled or that the error indicates corruption — it does not.","solutions":["Confirm which opcode value appears in the message; only 14 (SQLITE_FCNTL_PRAGMA) is supported","If it comes from SQLite's internal probing, treat it as benign/not-applicable and ensure the caller handles the error as 'not supported'","Route PRAGMA operations via PRAGMA statements so they arrive as op 14","If a needed op is legitimately required (e.g. size hint or persist-WAL), extend FileControl to handle or gracefully ignore that opcode","Check the litestream VFS version for added opcode support"],"exampleFix":"// before\nresult, err := file.Control(SOME_FCNTL_OP, \"\", nil)\nif err != nil { panic(err) }\n// after\nresult, err := file.Control(SOME_FCNTL_OP, \"\", nil)\nif err != nil {\n    if strings.Contains(err.Error(), \"unsupported file control op\") {\n        return nil // op not supported by this VFS; proceed without it\n    }\n    return err\n}\n// or use PRAGMA instead:\ndb.Exec(\"PRAGMA litestream_txid\")","handlingStrategy":"try-catch","validationCode":"// Only issue op 14 (SQLITE_FCNTL_PRAGMA) through this VFS; prefer PRAGMA statements:\nconst SQLITE_FCNTL_PRAGMA = 14\nif op != SQLITE_FCNTL_PRAGMA {\n    // skip: this VFS only supports PRAGMA file controls\n    return\n}","typeGuard":"func isPragmaFileControl(op int) bool { return op == 14 }","tryCatchPattern":"_, err := file.FileControl(op, name, val)\nif err != nil {\n    var unsupported bool\n    if strings.Contains(err.Error(), \"unsupported file control op\") {\n        unsupported = true // treat as not-implemented, degrade gracefully\n    }\n    _ = unsupported\n}","preventionTips":["Use PRAGMA statements (they map to op 14) instead of raw xFileControl calls","Treat this error as 'feature not supported' and no-op, matching SQLite conventions","Keep the SQLite driver/library version compatible with the litestream VFS build","When adding VFS features, extend FileControl with explicit opcode handling"],"tags":["go","sqlite","vfs","file-control"],"backgroundTag":"unsupported-operation","analyzedSha":"4ed7a308f6271ebfd2b0a6e4b70b03011a37e4a3","analyzedAt":"2026-09-06T18:29:25.564Z","contentChangedAt":"2026-09-06T18:29:25.564Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}