{"record":{"id":"8aa002083ab3cfcc","repo":"mudler/LocalAI","slug":"ds4-worker-role-worker-is-required","errorCode":null,"errorMessage":"ds4-worker: --role worker is required\n","messagePattern":"ds4-worker: --role worker is required\n","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"backend/cpp/ds4/worker_main.c","lineNumber":100,"sourceCode":"            opt.model_path = need_arg(&i, argc, argv, arg);\n        } else if (!strcmp(arg, \"-c\") || !strcmp(arg, \"--ctx\")) {\n            ctx_size = parse_int_arg(need_arg(&i, argc, argv, arg), arg);\n        } else if (!strcmp(arg, \"-t\") || !strcmp(arg, \"--threads\")) {\n            opt.n_threads = parse_int_arg(need_arg(&i, argc, argv, arg), arg);\n        } else if (!strcmp(arg, \"--cpu\")) {\n            opt.backend = DS4_BACKEND_CPU;\n        } else if (!strcmp(arg, \"--cuda\")) {\n            opt.backend = DS4_BACKEND_CUDA;\n        } else if (!strcmp(arg, \"--metal\")) {\n            opt.backend = DS4_BACKEND_METAL;\n        } else {\n            fprintf(stderr, \"ds4-worker: unknown option: %s\\n\", arg);\n            return 2;\n        }\n    }\n\n    if (opt.distributed.role != DS4_DISTRIBUTED_WORKER) {\n        fprintf(stderr, \"ds4-worker: --role worker is required\\n\");\n        return 2;\n    }\n    if (!opt.model_path) {\n        fprintf(stderr, \"ds4-worker: --model is required\\n\");\n        return 2;\n    }\n\n    char prep_err[256] = {0};\n    if (ds4_dist_prepare_engine_options(&opt.distributed, &opt,\n                                        prep_err, sizeof(prep_err)) != 0) {\n        fprintf(stderr, \"ds4-worker: %s\\n\", prep_err);\n        return 2;\n    }\n\n    ds4_engine *engine = NULL;\n    if (ds4_engine_open(&engine, &opt) != 0 || !engine) {\n        fprintf(stderr, \"ds4-worker: failed to open engine\\n\");\n        return 1;","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/mudler/LocalAI/blob/44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26/backend/cpp/ds4/worker_main.c#L82-L118","documentation":"Post-parse invariant check in ds4-worker: after argument parsing, opt.distributed.role must equal DS4_DISTRIBUTED_WORKER. The binary is exclusively a worker — it has no driver/coordinator code path — so starting it without '--role worker' (or with a role value that did not set the enum) exits with status 2 before touching the model or network.","triggerScenarios":"Running 'ds4-worker -m model.gguf --layers 8' with no --role flag, or launching it as if it were the standalone server; the role field stays at its zero value which is not DS4_DISTRIBUTED_WORKER.","commonSituations":"Adapting a single-node command line for distributed runs and forgetting the role; orchestration templates that omit --role; assuming the binary name alone implies the role.","solutions":["Add '--role worker' to the command line.","Keep one canonical argv per role in your launcher templates (worker vs driver) so the flag cannot be dropped.","Validate with 'ds4-worker --help' that the assembled command parses before deploying."],"exampleFix":"# before\nds4-worker -m /m.gguf --layers 8\n\n# after\nds4-worker --role worker -m /m.gguf --layers 8","handlingStrategy":"validation","validationCode":"# launcher invariant: role flag must be present exactly once\ncase \" $* \" in *' --role worker '*) : ;; *) echo \"ds4-worker requires --role worker\" >&2; exit 2;; esac\nexec ds4-worker \"$@\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Template one argv per role (worker/driver) so the flag is baked in, never appended by hand.","Smoke-test the exact worker command in CI so a dropped --role fails the pipeline, not the node."],"tags":["c","ds4","cli","distributed","usage-error"],"backgroundTag":null,"analyzedSha":"44413a9d06bf5bc52ce088ba8ca74e5a2e8bee26","analyzedAt":"2026-08-15T10:13:50.291Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}