JuliusBrussee/caveman · error
session-value artifact version identity invalid
Error message
session-value artifact version identity invalid
What it means
The artifact must identify how it was built and which evaluator can run it: PolicyVersion must be >= 1, RouterVersion must be exactly "session-value-v1", and EstimatorVersion must be non-empty. A mismatch means the coefficients were trained for a different router or estimator generation and cannot be interpreted by this evaluator.
Source
Thrown at proxy/routing/session_value.go:172
func SealSessionValueArtifact(artifact SessionValuePolicyArtifact) (SessionValuePolicyArtifact, error) {
hash, err := ComputeSessionValueArtifactHash(artifact)
if err != nil {
return SessionValuePolicyArtifact{}, err
}
artifact.ArtifactHash = hash
return artifact, nil
}
func ValidateSessionValueArtifact(artifact SessionValuePolicyArtifact, organizationID, projectID, candidatePoolHash string, now time.Time) error {
if artifact.Schema != SessionValueArtifactSchema || artifact.StateSchemaVersion != SessionValueStateSchema {
return errors.New("session-value artifact schema mismatch")
}
if strings.TrimSpace(artifact.OrganizationID) == "" || artifact.OrganizationID != strings.TrimSpace(organizationID) ||
strings.TrimSpace(artifact.ProjectID) == "" || artifact.ProjectID != strings.TrimSpace(projectID) {
return errors.New("session-value artifact tenant scope mismatch")
}
if artifact.PolicyVersion <= 0 || artifact.RouterVersion != SessionValueRouterVersion || strings.TrimSpace(artifact.EstimatorVersion) == "" {
return errors.New("session-value artifact version identity invalid")
}
if !validCompactPoolHash(artifact.CandidatePoolHash) || artifact.CandidatePoolHash != candidatePoolHash {
return errors.New("session-value artifact candidate pool mismatch")
}
if !validSHA256Ref(artifact.TrainingManifestHash) || strings.TrimSpace(artifact.TrainingExtractor) == "" || strings.TrimSpace(artifact.OutcomeContractVersion) == "" {
return errors.New("session-value artifact training lineage invalid")
}
if artifact.ValidFrom.IsZero() || artifact.ValidUntil.IsZero() || !artifact.ValidUntil.After(artifact.ValidFrom) || now.Before(artifact.ValidFrom) || !now.Before(artifact.ValidUntil) {
return errors.New("session-value artifact outside validity window")
}
if artifact.RollbackParentHash != "" && (!validSHA256Ref(artifact.RollbackParentHash) || artifact.RollbackParentHash == artifact.ArtifactHash) {
return errors.New("session-value artifact rollback lineage invalid")
}
if !finite(artifact.QualityUncertaintyZ) || artifact.QualityUncertaintyZ <= 0 || artifact.QualityUncertaintyZ > 5 ||
!finite(artifact.MaxInversePropensity) || artifact.MaxInversePropensity < 1 || artifact.MaxInversePropensity > 100 {
return errors.New("session-value artifact confidence policy invalid")
}
featureNames := SessionValueFeatureNames()View on GitHub (pinned to 766dce6b13)
Solutions
- Regenerate the artifact with the current trainer so router_version and estimator_version are stamped correctly.
- Upgrade the router to the version the artifact targets, or keep artifacts grouped per router generation.
- Set policy_version to a monotonically increasing positive integer during training instead of relying on defaults.
Example fix
// before
{
"policy_version": 0,
"router_version": "session-value-v0",
"estimator_version": ""
}
// after
{
"policy_version": 1,
"router_version": "session-value-v1",
"estimator_version": "lin-est-2026-05"
} Defensive patterns
Strategy: validation
Validate before calling
// Before validation: check version identity fields.
if artifact.PolicyVersion < 1 ||
artifact.RouterVersion != routing.SessionValueRouterVersion ||
strings.TrimSpace(artifact.EstimatorVersion) == "" {
return fmt.Errorf("artifact built for router %q policy %d estimator %q; this router runs %q",
artifact.RouterVersion, artifact.PolicyVersion, artifact.EstimatorVersion,
routing.SessionValueRouterVersion)
} Type guard
func artifactVersionCompatible(a routing.SessionValuePolicyArtifact) bool {
return a.PolicyVersion >= 1 &&
a.RouterVersion == routing.SessionValueRouterVersion &&
strings.TrimSpace(a.EstimatorVersion) != ""
} Prevention
- Stamp router_version and estimator_version automatically during training; fail the build when either is empty.
- Keep a registry of policy_version increments so zero never ships.
- Treat router-version mismatches as deploy-blockers in CI, not runtime surprises.
When it happens
Trigger: PolicyVersion left at the Go zero value 0 by the artifact generator; RouterVersion carried from a newer evaluator (for example a hypothetical session-value-v2); the estimator_version field dropped or renamed during JSON refactoring so it unmarshals empty.
Common situations: Router upgraded to a new evaluation format while artifacts still carry the old router version string; training pipeline forgetting to stamp versions; manual artifact editing that clears fields.
Related errors
- session-value artifact schema mismatch
- session-value artifact confidence policy invalid
- session-value artifact tenant scope mismatch
- session-value artifact candidate pool mismatch
- session-value artifact outside validity window
AI-assisted analysis of JuliusBrussee/caveman@766dce6b13 (2026-08-18).
Data as JSON: /api/errors/bd0651f0b1e85435.
Report an issue: GitHub.