{"record":{"id":"6f088081b90304dc","repo":"apache/pulsar","slug":"componenttype-package-is-not-provided","errorCode":null,"errorMessage":"${componentType} Package is not provided","messagePattern":"(.+?) Package is not provided","errorType":"http","errorClass":"IllegalArgumentException","httpStatus":400,"severity":"error","filePath":"pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java","lineNumber":343,"sourceCode":"        }\n\n        FunctionDetails functionDetails;\n        File componentPackageFile = null;\n        try {\n\n            // validate parameters\n            try {\n                componentPackageFile = getPackageFile(\n                        componentType,\n                        sourcePkgUrl,\n                        existingComponent.getPackageLocation().getPackagePath(),\n                        uploadedInputStream);\n                functionDetails = validateUpdateRequestParams(tenant, namespace, sourceName,\n                        mergedConfig, componentPackageFile);\n                if (existingComponent.getPackageLocation().getPackagePath().startsWith(Utils.BUILTIN)\n                        && !isFunctionCodeBuiltin(functionDetails)\n                        && (componentPackageFile == null || fileDetail == null)) {\n                    throw new IllegalArgumentException(ComponentTypeUtils.toString(componentType)\n                            + \" Package is not provided\");\n                }\n            } catch (Exception e) {\n                log.error().attr(\"componentType\", ComponentTypeUtils.toString(componentType)).attr(\"tenant\", tenant)\n\n                        .attr(\"namespace\", namespace).attr(\"componentName\", sourceName).exception(e)\n\n                        .log(\"Invalid update request @ / / /\");\n                throw new RestException(Response.Status.BAD_REQUEST, e.getMessage());\n            }\n\n            try {\n                worker().getFunctionRuntimeManager().getRuntimeFactory().doAdmissionChecks(functionDetails);\n            } catch (Exception e) {\n                log.error().attr(\"componentType\", ComponentTypeUtils.toString(componentType)).attr(\"tenant\", tenant)\n\n                        .attr(\"namespace\", namespace).attr(\"componentName\", sourceName)\n","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/apache/pulsar/blob/820761864ed8e2a7d2e52dd9763ad2ae117c1395/pulsar-functions/worker/src/main/java/org/apache/pulsar/functions/worker/rest/api/SourcesImpl.java#L325-L361","documentation":"updateSource requires a package whenever an existing builtin source is being updated with non-builtin code: if the stored package path starts with builtin:// and the new FunctionDetails is not builtin, a package must be supplied (uploadedInputStream/fileDetail or package file). Otherwise an IllegalArgumentException is raised and wrapped as 400 BAD_REQUEST with '<componentType> Package is not provided'.","triggerScenarios":"Updating a source whose existing package location is builtin://... while the request neither is itself builtin nor provides componentPackageFile/fileDetail (no uploadedInputStream and no sourcePkgUrl download).","commonSituations":" Migrating a connector from a bundled builtin archive (built-in connectors under ./connectors) to a custom NAR/jar and forgetting to attach the new package file; switching the source class to a custom implementation while leaving the package unspecified.","solutions":["Attach the new package: multipart-upload the jar/nar (uploadedInputStream) or set sourcePkgUrl to the package location","If the updated code is still builtin, set the archive/class so isFunctionCodeBuiltin(functionDetails) is true (use builtin:// archive and a class contained in it)","Check FunctionConfig/SourceConfig archive field: use 'builtin://<connector>' for builtin code or provide the package file for custom code"],"exampleFix":"// before: updating builtin source to custom class with no package\ncfg.setClassName(\"com.custom.MySource\"); // archive still builtin://kafka\n// after: provide the custom package\ncfg.setArchive(\"file:///path/to/my-source.nar\"); // or upload via multipart\nadmin.sources().updateSource(tenant, ns, name, cfg, pkgUrl, null);","handlingStrategy":"validation","validationCode":"SourceConfig existing = admin.sources().getSourceConfig(tenant, ns, name);\nboolean wasBuiltin = existing.getArchive() != null && existing.getArchive().startsWith(\"builtin://\");\nboolean nowBuiltin = proposed.getArchive() != null && proposed.getArchive().startsWith(\"builtin://\");\nif (wasBuiltin && !nowBuiltin && pkgUrl == null && uploadStream == null) {\n    throw new IllegalArgumentException(\"Non-builtin source update requires a package file or sourcePkgUrl\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    admin.sources().updateSource(tenant, ns, name, cfg, pkgUrl, uploadStream);\n} catch (PulsarAdminException e) {\n    if (e.getStatusCode() == 400 && e.getMessage().contains(\"Package is not provided\")) {\n        log.error(\"Provide a jar/nar package when switching away from builtin code\");\n    } else { throw e; }\n}","preventionTips":["When replacing builtin connectors with custom code, always attach the package via multipart upload or package URL","Keep the archive field consistent: builtin://<name> for builtin, a valid package path otherwise","Verify the uploaded package is non-empty and a valid jar/nar before calling the API"],"tags":["rest-api","package-missing","pulsar-functions","builtin"],"backgroundTag":"connector-package-missing","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"}