hasura/graphql-engine · error
platform (%+v) is badly constructed: %w
Error message
platform (%+v) is badly constructed: %w
What it means
ValidatePlugin iterates p.Platforms and each entry must pass validatePlatform. This error wraps the underlying platform validation failure (missing/invalid os, arch, url, bin, sha256, or files) together with a dump of the offending platform struct, so you can identify which entry in the platforms array is malformed.
Source
Thrown at cli/plugins/types.go:155
return errors.E(op, "should have a short description")
}
if strings.ContainsAny(p.ShortDescription, "\r\n") {
return errors.E(op, "should not have line breaks in short description")
}
if len(p.Platforms) == 0 {
return errors.E(op, "should have a platform specified")
}
if p.Version == "" {
return errors.E(op, "should have a version specified")
}
for _, pl := range p.Platforms {
err := validatePlatform(pl)
if err != nil {
return errors.E(op, fmt.Errorf("platform (%+v) is badly constructed: %w", pl, err))
}
}
return nil
}
// Platform describes how to perform an installation on a specific platform
// and how to match the target platform (os, arch).
type Platform struct {
URI string `json:"uri,omitempty"`
Sha256 string `json:"sha256,omitempty"`
Files []FileOperation `json:"files"`
Selector string `json:"selector"`
// Bin specifies the path to the plugin executable.
// The path is relative to the root of the installation folder.
// The binary will be linked after all FileOperations are executed.
Bin string `json:"bin"`
}View on GitHub (pinned to 724551b9ae)
Solutions
- Read the wrapped error text after the colon — it names the exact missing field (e.g. "`bin` has to be set").
- Match the failing entry against the %+v dump printed in the message to find its index in p.Platforms.
- Fill in all required platform fields: os, arch, url, sha256 (hex, matching sha256Pattern), bin, and valid files operations.
Example fix
// before
"platforms": [{ "os": "linux", "arch": "amd64", "url": "https://...", "bin": "" }]
// after
"platforms": [{ "os": "linux", "arch": "amd64", "url": "https://...", "sha256": "<64 hex chars>", "bin": "myplugin" }] Defensive patterns
Strategy: validation
Validate before calling
for i, pl := range p.Platforms {
if err := validatePlatform(pl); err != nil { // or your own equivalent checks
return fmt.Errorf("platform[%d] (%s/%s): %w", i, pl.Os, pl.Arch, err)
}
} Try / catch
if err := p.ValidatePlugin(name); err != nil {
if strings.Contains(err.Error(), "badly constructed") {
// the wrapped message names the missing field; fix that platform entry
}
} Prevention
- Fill every required platform field: os, arch, url, sha256, bin, files.
- Validate manifests in CI before release using ReadPluginFromFile.
- Use a JSON schema for plugin manifests so editors catch missing fields early.
When it happens
Trigger: A platforms[] entry in the plugin manifest missing required fields — e.g. no "os"/"arch", empty "url", missing "sha256", empty "bin", or an invalid files list — surfaced when ReadPluginFromFile → ValidatePlugin runs.
Common situations: Hand-written plugin manifests missing the sha256 sum; platform entries copied from another plugin with the wrong os/arch keys; entries where "bin" path doesn't match the archive layout.
Related errors
- the plugin name %q is not allowed, must match %q
- plugin should be named %q, not %q
- `sha256` value %s is not valid, must match pattern %s
- `files` is invalid: %w
- plugin %q does not offer installation for this platform
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/5c3483ad8f3ef93a.
Report an issue: GitHub.