{"record":{"id":"92815be59d4ddc96","repo":"grafana/k6","slug":"missing-or-empty-type-field","errorCode":null,"errorMessage":"missing or empty type field","messagePattern":"missing or empty type field","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/executor/base_config.go","lineNumber":63,"sourceCode":"\t\tGracefulStop: types.NewNullDuration(DefaultGracefulStopValue, false),\n\t}\n}\n\n// Validate checks some basic things like present name, type, and a positive start time\nfunc (bc BaseConfig) Validate() (result []error) {\n\t// Some just-in-case checks, since those things are likely checked in other places or\n\t// even assigned by us:\n\tif bc.Name == \"\" {\n\t\tresult = append(result, errors.New(\"scenario name can't be empty\"))\n\t}\n\tif !scenarioNameWhitelist.MatchString(bc.Name) {\n\t\tresult = append(result, errors.New(scenarioNameErr))\n\t}\n\tif bc.Exec.Valid && bc.Exec.String == \"\" {\n\t\tresult = append(result, errors.New(\"exec value cannot be empty\"))\n\t}\n\tif bc.Type == \"\" {\n\t\tresult = append(result, errors.New(\"missing or empty type field\"))\n\t}\n\t// The actually reasonable checks:\n\tif bc.StartTime.Duration < 0 {\n\t\tresult = append(result, errors.New(\"the startTime can't be negative\"))\n\t}\n\tif bc.GracefulStop.Duration < 0 {\n\t\tresult = append(result, errors.New(\"the gracefulStop timeout can't be negative\"))\n\t}\n\treturn result\n}\n\n// GetName returns the name of the scenario.\nfunc (bc BaseConfig) GetName() string {\n\treturn bc.Name\n}\n\n// GetType returns the executor's type as a string ID.\nfunc (bc BaseConfig) GetType() string {","sourceCodeStart":45,"sourceCodeEnd":81,"githubUrl":"https://github.com/grafana/k6/blob/93accf6570dcd306ca5e99cc44c393ee3797761b/lib/executor/base_config.go#L45-L81","documentation":"Emitted by BaseConfig.Validate (lib/executor/base_config.go:62-64) when the scenario's executor/type field is empty. The type (JSON key 'executor', line 29) selects the execution strategy (constant-vus, ramping-vus, constant-arrival-rate, ramping-arrival-rate, shared-iterations, per-vu-iterations); k6 cannot instantiate an executor without it. Note Validate() only reports a missing type at this base level — an unknown type string fails earlier during unmarshaling in lib/executor.Decode.","triggerScenarios":"Defining options.scenarios = { smoke: { vus: 1, duration: '10s' } } without an executor key, or programmatically building a BaseConfig with Type left as its zero value and calling Validate().","commonSituations":"Copy-paste of a scenario block that loses the executor line; assuming duration+vus alone imply constant-vus (they do not in the scenarios API); typos like 'executor' vs 'execution' are instead rejected at JSON decode with a different error.","solutions":["Add an explicit executor field, e.g. executor: 'constant-vus' with vus and duration","Pick the executor matching intent: shared-iterations, per-vu-iterations, constant-arrival-rate, ramping-arrival-rate, constant-vus, ramping-vus"],"exampleFix":"// before\nexport const options = {\n  scenarios: {\n    smoke: { vus: 1, duration: '10s' },\n  },\n};\n\n// after\nexport const options = {\n  scenarios: {\n    smoke: { executor: 'constant-vus', vus: 1, duration: '10s' },\n  },\n};","handlingStrategy":"validation","validationCode":"const VALID = new Set(['shared-iterations','per-vu-iterations','constant-vus','ramping-vus','constant-arrival-rate','ramping-arrival-rate']);\nfor (const [name, cfg] of Object.entries(options.scenarios || {})) {\n  if (!VALID.has(cfg.executor)) throw new Error(`scenario ${name}: missing/unknown executor`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always start a scenario block by choosing the executor first, then fill its specific options","Keep the k6 scenarios docs table handy: each executor has required fields (vus/duration vs startRate/stages)"],"tags":["config","scenarios","executor","validation"],"backgroundTag":null,"analyzedSha":"93accf6570dcd306ca5e99cc44c393ee3797761b","analyzedAt":"2026-08-15T21:23:27.118Z","schemaVersion":2},"datasetVersion":"2026-08-16T03:17:38.424Z"}