{"record":{"id":"97745e7fc4bbeee0","repo":"JanDeDobbeleer/oh-my-posh","slug":"data-only-and-data-derive-contradict-each-othe","errorCode":null,"errorMessage":"--data-only and --data-derive contradict each other: one forbids probing the environment, the other forces it","messagePattern":"--data-only and --data-derive contradict each other: one forbids probing the environment, the other forces it","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/data.go","lineNumber":63,"sourceCode":"\t}\n\n\tif data.Version < config.DataVersion {\n\t\tfmt.Fprintf(os.Stderr,\n\t\t\t\"warning: %s has no recorder version marker; treating it as hand-written - it is neither hermetic nor deterministic, \"+\n\t\t\t\t\"segments left out of it still probe the live environment. Run `oh-my-posh config export data` to record a deterministic file.\\n\",\n\t\t\tdataPath)\n\t}\n\n\tif dataDerive && data.Version >= config.DataVersion {\n\t\tdata.Segments = deriveRecordedSegments(data.Segments)\n\t}\n\n\t// --data-only and --data-derive are opposites: one forbids probing\n\t// entirely, the other forces it even for a recorded file. Asking for both\n\t// is a contradiction rather than a combination, so say so instead of\n\t// silently letting one win.\n\tif dataOnly && dataDerive {\n\t\treturn errors.New(\"--data-only and --data-derive contradict each other: one forbids probing the environment, the other forces it\")\n\t}\n\n\tflags.DataOnly = dataOnly\n\n\treturn data.ApplyFlags(flags, changed)\n}\n\n// deriveRecordedSegments strips the RecordedSegment envelope back down to each\n// segment's raw writer data, forcing Segment.restoreData to treat a recorded\n// file the same way it treats a hand-written one: derive live state via\n// writer.Enabled(), then overlay the pinned data, instead of the hermetic no-probe\n// path. The caller only calls this once data.Version confirms every entry is an\n// envelope, so decoding here does not need to guard against a flat entry.\nfunc deriveRecordedSegments(segments map[string]json.RawMessage) map[string]json.RawMessage {\n\tderived := make(map[string]json.RawMessage, len(segments))\n\n\tfor key, raw := range segments {\n\t\tvar recorded config.RecordedSegment","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/JanDeDobbeleer/oh-my-posh/blob/0976794618c5ed95de0985dded50de1b4dc914cb/src/cli/data.go#L45-L81","documentation":"applyDataFile in the data CLI rejects a combination of mutually exclusive flags. `--data-only` forbids any environment probing while applying data-file overrides, whereas `--data-derive` forces probing even for recorded files. Supplying both is defined as a contradiction, so the call fails fast instead of silently preferring one flag.","triggerScenarios":"Calling applyDataFile (via the `data` command's apply path) with both dataOnly=true and dataDerive=true — e.g. `oh-my-posh data apply --data-only --data-derive --file state.json`, or a wrapper script that hardcodes both flags.","commonSituations":"Users assuming the flags are orthogonal and combining them 'to be safe'; shell aliases or wrapper scripts accumulating flags over time; CI configs where one flag comes from a variable that defaults to on.","solutions":["Remove one of the two flags: pass --data-only if you want a pure replay with no probing, or --data-derive if you want forced derivation.","Audit wrapper scripts/aliases so only one of the flags is ever emitted.","In CI, ensure mutually exclusive flag variables cannot both evaluate to true before invoking the command."],"exampleFix":"// before\nflags := []string{\"--data-only\", \"--data-derive\", \"--file\", \"state.json\"}\n// after\nflags := []string{\"--data-only\", \"--file\", \"state.json\"} // or --data-derive, never both","handlingStrategy":"validation","validationCode":"if dataOnly && dataDerive {\n    return errors.New(\"choose either --data-only or --data-derive, not both\")\n}","typeGuard":null,"tryCatchPattern":"if err := applyDataFile(path, flags, changed); err != nil {\n    if strings.Contains(err.Error(), \"contradict\") {\n        fmt.Fprintln(os.Stderr, \"fix your flag combination: --data-only and --data-derive are mutually exclusive\")\n        os.Exit(2)\n    }\n    return err\n}","preventionTips":["Model exclusive flags as a single enum (mode=only|derive) instead of two booleans in wrapper scripts","Sanity-check assembled CLI arguments in CI before invoking the command","Read the flag help: flags described as opposites are usually mutually exclusive"],"tags":["cli","flags","mutually-exclusive","validation"],"backgroundTag":"mutually-exclusive-flags","analyzedSha":"0976794618c5ed95de0985dded50de1b4dc914cb","analyzedAt":"2026-08-31T23:41:19.708Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T05:18:18.240Z"}