{"record":{"id":"8c4ba12af2cdaa76","repo":"pulumi/pulumi","slug":"deletebeforereplace-must-be-a-boolean-or-null","errorCode":null,"errorMessage":"deleteBeforeReplace must be a boolean or null","messagePattern":"deleteBeforeReplace must be a boolean or null","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/pcl/runtime/interpreter.go","lineNumber":1740,"sourceCode":"\t\t\t\t\tDelete: timeoutValues[\"delete\"],\n\t\t\t\t\tRead:   timeoutValues[\"read\"],\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif res.Options.DeleteBeforeReplace != nil {\n\t\t\tdbr, poison, diags := evalCtx.Evaluate(res.Options.DeleteBeforeReplace)\n\t\t\tif poison != nil {\n\t\t\t\treturn makePoisonValue(*poison), nil\n\t\t\t}\n\t\t\tif diags.HasErrors() {\n\t\t\t\treturn cty.NilVal, diags\n\t\t\t}\n\t\t\tif !dbr.IsNull() && !dbr.IsComputed() {\n\t\t\t\tif dbr.IsBool() {\n\t\t\t\t\trequest.DeleteBeforeReplace = dbr.BoolValue()\n\t\t\t\t\trequest.DeleteBeforeReplaceDefined = true\n\t\t\t\t} else if !dbr.IsNull() {\n\t\t\t\t\treturn cty.NilVal, errors.New(\"deleteBeforeReplace must be a boolean or null\")\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif res.Options.DeletedWith != nil {\n\t\t\tdeletedWith, poison, diags := evalCtx.Evaluate(res.Options.DeletedWith)\n\t\t\tif poison != nil {\n\t\t\t\treturn makePoisonValue(*poison), nil\n\t\t\t}\n\t\t\tif diags.HasErrors() {\n\t\t\t\treturn cty.NilVal, diags\n\t\t\t}\n\t\t\tif !deletedWith.IsNull() && !deletedWith.IsComputed() {\n\t\t\t\turn, _, err := unwrapResource(deletedWith)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn cty.NilVal, fmt.Errorf(\"deletedWith: %w\", err)\n\t\t\t\t}\n\t\t\t\trequest.DeletedWith = urn\n\t\t\t}","sourceCodeStart":1722,"sourceCodeEnd":1758,"githubUrl":"https://github.com/pulumi/pulumi/blob/793f7b2e160db4321fb7fb6b0607461e01cb251e/pkg/pcl/runtime/interpreter.go#L1722-L1758","documentation":"The deleteBeforeReplace resource option must evaluate to a boolean or null. This error is raised when the option evaluates to some other cty type (string, number, object). The interpreter only accepts IsBool values and otherwise fails with this message.","triggerScenarios":"Passing options {deleteBeforeReplace: \"true\"} (string) or {deleteBeforeReplace: 1} to a resource in a PCL program evaluated by the PCL runtime (interpreter.go:1740).","commonSituations":"Copy-pasting options from YAML/JSON where booleans are quoted strings; interpolating a computed string into the option; typos like \"yes\"/\"no\".","solutions":["Use a real boolean literal: options { deleteBeforeReplace: true }","Remove quotes from boolean values inherited from JSON/YAML snippets","If the value is dynamic, ensure the expression evaluates to a bool type, not a string"],"exampleFix":"// before\noptions = { deleteBeforeReplace: \"true\" }\n// after\noptions = { deleteBeforeReplace: true }","handlingStrategy":"type-guard","validationCode":"// Before running, reject non-bool deleteBeforeReplace\nif v, ok := opts[\"deleteBeforeReplace\"]; ok {\n    switch v.(type) {\n    case bool, nil:\n    default:\n        return fmt.Errorf(\"deleteBeforeReplace must be a bool or null, got %T\", v)\n    }\n}","typeGuard":"func isBoolOrNil(v any) bool {\n    switch v.(type) {\n    case bool, nil:\n        return true\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["Use unquoted true/false literals, never \"true\"/\"false\" strings","Check values sourced from YAML/JSON where booleans often arrive as strings","Add a config lint that asserts bool types for boolean options"],"tags":["pcl","resource-options","type-validation"],"backgroundTag":"invalid-option-type","analyzedSha":"793f7b2e160db4321fb7fb6b0607461e01cb251e","analyzedAt":"2026-08-31T09:36:43.099Z","schemaVersion":2},"datasetVersion":"2026-09-01T08:17:40.651Z"}