{"record":{"id":"36cc78a0640708db","repo":"vitessio/vitess","slug":"action-requires-only-one-of-v-or-v-file","errorCode":null,"errorMessage":"action requires only one of %v or %v-file","messagePattern":"action requires only one of (.+?) or (.+?)-file","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vtctl/vtctl.go","lineNumber":814,"sourceCode":"\t\tkeyspace = \"<null>\"\n\t}\n\tif shard == \"\" {\n\t\tshard = \"<null>\"\n\t}\n\tmtst := \"<null>\"\n\t// special case for old primary that hasn't updated topo yet\n\tif ti.PrimaryTermStartTime != nil && ti.PrimaryTermStartTime.Seconds > 0 {\n\t\tmtst = protoutil.TimeFromProto(ti.PrimaryTermStartTime).UTC().Format(time.RFC3339)\n\t}\n\treturn fmt.Sprintf(\"%v %v %v %v %v %v %v %v\", topoproto.TabletAliasString(ti.Alias), keyspace, shard, topoproto.TabletTypeLString(ti.Type), ti.Addr(), ti.MysqlAddr(), fmtMapAwkable(ti.Tags), mtst)\n}\n\n// getFileParam returns a string containing either flag is not \"\",\n// or the content of the file named flagFile\nfunc getFileParam(flag, flagFile, name string) (string, error) {\n\tif flag != \"\" {\n\t\tif flagFile != \"\" {\n\t\t\treturn \"\", fmt.Errorf(\"action requires only one of %v or %v-file\", name, name)\n\t\t}\n\t\treturn flag, nil\n\t}\n\n\tif flagFile == \"\" {\n\t\treturn \"\", fmt.Errorf(\"action requires one of %v or %v-file\", name, name)\n\t}\n\tdata, err := os.ReadFile(flagFile)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"cannot read file %v: %v\", flagFile, err)\n\t}\n\treturn string(data), nil\n}\n\n// keyspaceParamsToKeyspaces builds a list of keyspaces.\n// It supports topology-based wildcards, and plain wildcards.\n// For instance:\n// us*                             // using plain matching","sourceCodeStart":796,"sourceCodeEnd":832,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vtctl/vtctl.go#L796-L832","documentation":"getFileParam resolves a value that may be supplied either inline via a flag or via a file flag. If BOTH the inline flag and the -file flag are set, it refuses with this error since only one source is allowed.","triggerScenarios":"Calling ApplySchema (or similar commands using getFileParam, e.g. for the `sql` parameter) with both e.g. `--sql \"...\"` and `--sql-file schema.sql` set at the same time.","commonSituations":"Script/template assembling a command line where the inline value is a default and a file path was appended; combining legacy and new flags in automation; copy-pasted command lines accumulating flags.","solutions":["Remove either the inline flag or the -file flag so exactly one is provided.","If automation sets both, prefer the -file flag and blank the inline one (or vice versa).","Audit the wrapper script for unconditional flag defaults that collide with user-supplied file flags."],"exampleFix":"// before\nApplySchema --sql \"ALTER TABLE t ADD COLUMN c INT\" --sql-file schema.sql commerce\n// after\nApplySchema --sql-file schema.sql commerce","handlingStrategy":"validation","validationCode":"if sqlFlag && sqlFileFlag {\n  panic(\"ApplySchema: provide only one of --sql or --sql-file\")\n}","typeGuard":"null","tryCatchPattern":"try {\n  run(\"vtctlclient ApplySchema --sql ... --sql-file ... commerce\")\n} catch (e) {\n  if (String(e).includes(\"requires only one of\")) {\n    console.error(\"Drop either the inline flag or the -file flag and retry\")\n  } else throw e\n}","preventionTips":["In wrapper scripts, emit at most one of the inline and -file flags.","Validate flag combinations before exec'ing vtctlclient.","Make file-based input the single canonical path in CI pipelines."],"tags":["cli","flag-validation","apply-schema","mutually-exclusive-flags"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}