{"record":{"id":"4d1d89566b100967","repo":"apache/pulsar","slug":"function-language-runtime-is-either-not-set-or-can","errorCode":null,"errorMessage":"Function language runtime is either not set or cannot be determined","messagePattern":"Function language runtime is either not set or cannot be determined","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java","lineNumber":975,"sourceCode":"            retval.addAll(functionConfig.getCustomSerdeInputs().keySet());\n        }\n        if (functionConfig.getCustomSchemaInputs() != null) {\n            retval.addAll(functionConfig.getCustomSchemaInputs().keySet());\n        }\n        if (functionConfig.getInputSpecs() != null) {\n            retval.addAll(functionConfig.getInputSpecs().keySet());\n        }\n        return retval;\n    }\n\n    public static void validateNonJavaFunction(FunctionConfig functionConfig) {\n        doCommonChecks(functionConfig);\n        if (functionConfig.getRuntime() == FunctionConfig.Runtime.GO) {\n            doGolangChecks(functionConfig);\n        } else if (functionConfig.getRuntime() == FunctionConfig.Runtime.PYTHON) {\n            doPythonChecks(functionConfig);\n        } else {\n            throw new IllegalArgumentException(\"Function language runtime is either not set or cannot be determined\");\n        }\n    }\n\n    public static ExtractedFunctionDetails validateJavaFunction(FunctionConfig functionConfig,\n                                                                ValidatableFunctionPackage validatableFunctionPackage) {\n        doCommonChecks(functionConfig);\n        return doJavaChecks(functionConfig, validatableFunctionPackage);\n    }\n\n    public static FunctionConfig validateUpdate(FunctionConfig existingConfig, FunctionConfig newConfig) {\n        FunctionConfig mergedConfig = existingConfig.toBuilder().build();\n        if (!existingConfig.getTenant().equals(newConfig.getTenant())) {\n            throw new IllegalArgumentException(\"Tenants differ\");\n        }\n        if (!existingConfig.getNamespace().equals(newConfig.getNamespace())) {\n            throw new IllegalArgumentException(\"Namespaces differ\");\n        }\n        if (!existingConfig.getName().equals(newConfig.getName())) {","sourceCodeStart":957,"sourceCodeEnd":993,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/utils/src/main/java/org/apache/pulsar/functions/utils/FunctionConfigUtils.java#L957-L993","documentation":"validateNonJavaFunction dispatches to language-specific checks based on functionConfig.getRuntime(). This error is thrown when the runtime field is null or set to a runtime other than GO or PYTHON while the function is not a Java function (no className), so the framework cannot determine how to run it.","triggerScenarios":"Submitting/updating a non-Java function whose FunctionConfig has runtime == null, or runtime set to JAVA when className/jar are absent, or any value outside {GO, PYTHON} in the non-Java validation path.","commonSituations":"Config files created by hand that omit the `runtime: PYTHON|GO` field; programmatic builders that forget setRuntime(); tooling upgrades where the runtime enum name changed or a generic 'function' type was assumed.","solutions":["Set the runtime explicitly: functionConfig.setRuntime(FunctionConfig.Runtime.PYTHON) or FunctionConfig.Runtime.GO as appropriate.","Verify the config file has a valid `runtime: ` key (GO_PYTHON style names must match the Runtime enum).","If the function is Java, use the Java validation path and set className plus jar containing the function."],"exampleFix":"// before\nFunctionConfig config = FunctionConfig.builder().className(\"\").build(); // runtime unset\n// after\nFunctionConfig config = FunctionConfig.builder()\n    .runtime(FunctionConfig.Runtime.PYTHON)\n    .py(\"/path/to/func.py\")\n    .build();","handlingStrategy":"validation","validationCode":"if (cfg.getRuntime() == null) {\n    throw new IllegalArgumentException(\"runtime must be explicitly set (GO or PYTHON) for non-Java functions\");\n}","typeGuard":"boolean hasValidRuntime(FunctionConfig c) {\n    return c.getRuntime() == FunctionConfig.Runtime.GO || c.getRuntime() == FunctionConfig.Runtime.PYTHON;\n}","tryCatchPattern":"try {\n    FunctionConfigUtils.validateNonJavaFunction(config);\n} catch (IllegalArgumentException e) {\n    if (e.getMessage().contains(\"language runtime\")) {\n        throw new IllegalStateException(\"Set FunctionConfig.Runtime (PYTHON/GO) before submitting\", e);\n    } else { throw e; }\n}","preventionTips":["Always set runtime explicitly in builders and YAML configs.","Use enum values, not strings, for runtime to catch typos at compile time.","Route Java functions to the Java validation path (className + jar) instead."],"tags":["pulsar-functions","config-validation","runtime"],"backgroundTag":"missing-required-config-field","analyzedSha":"820761864ed8e2a7d2e52dd9763ad2ae117c1395","analyzedAt":"2026-09-06T00:14:20.138Z","contentChangedAt":"2026-09-06T00:14:20.138Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}