hyperledger/fabric · error
chaincode language must be specified
Error message
chaincode language must be specified
What it means
PackageInput.Validate returns this when the --lang flag is empty. The language selects which platform packager (golang, java, node) builds the deployment payload and it is also written into metadata.json. Packaging cannot proceed without a known chaincode language.
Source
Thrown at internal/peer/lifecycle/chaincode/package.go:54
Writer Writer
}
// PackageInput holds the input parameters for packaging a
// ChaincodeInstallPackage
type PackageInput struct {
OutputFile string
Path string
Type string
Label string
}
// Validate checks for the required inputs
func (p *PackageInput) Validate() error {
if p.Path == "" {
return errors.New("chaincode path must be specified")
}
if p.Type == "" {
return errors.New("chaincode language must be specified")
}
if p.OutputFile == "" {
return errors.New("output file must be specified")
}
if p.Label == "" {
return errors.New("package label must be specified")
}
if err := persistence.ValidateLabel(p.Label); err != nil {
return err
}
return nil
}
// PackageCmd returns the cobra command for packaging chaincode
func PackageCmd(p *Packager) *cobra.Command {
chaincodePackageCmd := &cobra.Command{
Use: "package [outputfile]",View on GitHub (pinned to 2736b63f8f)
Solutions
- Add the flag: --lang golang (or java / node) to the package command.
- Verify the shell variable (e.g. CC_RUNTIME_LANGUAGE) is exported and non-empty before the call.
- Ensure the value matches a supported platform since validation only checks emptiness here but GetDeploymentPayload does strings.ToUpper(p.Input.Type) later.
Example fix
// before
args := []string{"-p", path, "--label", label} // lang missing
// after
args := []string{"--lang", "golang", "--path", path, "--label", label} Defensive patterns
Strategy: validation
Validate before calling
#!/bin/bash
case "${CC_RUNTIME_LANGUAGE:-}" in
golang|java|node) ;;
*) echo "CC_RUNTIME_LANGUAGE must be golang, java, or node"; exit 1 ;;
esac
peer lifecycle chaincode package "$OUT" --path "$CC_SRC_PATH" --lang "$CC_RUNTIME_LANGUAGE" --label "$LABEL" Try / catch
if ! out=$(peer lifecycle chaincode package "$OUT" --path "$P" --lang "$L" --label "$LABEL" 2>&1); then
case "$out" in
*"chaincode language must be specified"*) echo "Add --lang golang|java|node"; exit 2 ;;
*) echo "$out"; exit 1 ;;
esac
fi Prevention
- Always pass --lang (golang/java/node) with the package command.
- Guard language variables with ${VAR:?} in CI scripts.
- Use lowercase language names; the tool uppercases internally.
- Pin the language in pipeline variables so it cannot go empty.
When it happens
Trigger: Running `peer lifecycle chaincode package` without --lang, or with an unset variable like $CC_RUNTIME_LANGUAGE that expands to empty.
Common situations: CI scripts where CC_RUNTIME_LANGUAGE was never set; docs examples using golang but the flag removed while editing; automation generating the CLI args programmatically and skipping the language field.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- chaincode path must be specified
- output file must be specified
- package label must be specified
- '%s' not equal <newest|oldest|config|(number)>
- Must supply channel ID
AI-assisted analysis of hyperledger/fabric@2736b63f8f (2026-09-04).
Data as JSON: /api/errors/fe7177c4ddd538a6.
Report an issue: GitHub.