Skip to content

fix(validation): use errorMessage from the data model when the definition has a nested $ref - #4390

Open
Bjarnisan wants to merge 2 commits into
Altinn:mainfrom
Bjarnisan:fix/schema-error-message-nested-ref
Open

Bjarnisan wants to merge 2 commits into
Altinn:mainfrom
Bjarnisan:fix/schema-error-message-nested-ref

Conversation

@Bjarnisan

@Bjarnisan Bjarnisan commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Description

A custom errorMessage in the data model was ignored when the field sat in a definition that itself contains a $ref, and the user got «Feil format eller verdi» instead. SchemaValidation looked up the field's schema from error.schemaPath, but AJV compiles such a definition separately and reports a path relative to it, so the lookup against the root schema found nothing. The issue has the steps and screenshots.

This PR uses error.parentSchema instead. AJV sets it because the validator is created with verbose: true, and it is the schema that failed, whether the definition was inlined or not. That also covers the rootElementPath case, so the getSchemaPartOldGenerator branch is no longer needed here.

getSchemaPart and getSchemaPartOldGenerator in src/utils/schemaUtils.ts are now only used by their own tests. I left them to keep this PR to the fix, and can remove them here or in a separate PR if you prefer.

An errorMessage placed beside a $ref ({ "$ref": "#/$defs/X", "errorMessage": "…" }) is not read before or after this change, since the error comes from the referenced definition. That is a separate case, and I have not changed it.

Same steps as in the issue, with app-frontend 4 from the CDN and with this branch, for Innsender.kontaktInfo.epost:

CDN (4) This branch
cdn-innsender-epost fix-innsender-epost

v9 has the same lookup in src/App/frontend in altinn-studio. I understand you sync changes from this repo over there, so I have not made a separate PR, but I am happy to make one if you prefer.

Related Issue(s)

Verification/QA

  • Manual functionality testing
    • I have tested these changes manually
    • Creator of the original issue (or service owner) has been contacted for manual testing (or will be contacted when released in alpha)
    • No testing done/necessary
  • Automated tests
    • Unit test(s) have been added/updated
    • Cypress E2E test(s) have been added/updated
    • No automatic tests are needed here (no functional changes/additions)
    • I want someone to help me make some tests
  • UU/WCAG (follow these guidelines until we have our own)
    • I have tested with a screen reader/keyboard navigation/automated wcag validator
    • No testing done/necessary (no DOM/visual changes)
    • I want someone to help me perform accessibility testing
  • User documentation @ altinn-studio-docs
    • Has been added/updated
    • No functionality has been changed/added, so no documentation is needed
    • I will do that later/have created an issue
  • Support in Altinn Studio
    • Issue(s) created for support in Studio
    • This change/feature does not require any changes to Altinn Studio
  • Sprint board
    • The original issue (or this PR itself) has been added to the Team Apps project and to the current sprint board
    • I don't have permissions to do that, please help me out
  • Labels
    • I have added a kind/* and backport* label to this PR for proper release notes grouping
    • I don't have permissions to add labels, please help me out

SchemaValidation.test.tsx has a new table test that checks that the field's errorMessage is used as the text key when the field is in:

  • a root property;
  • a definition without a nested $ref;
  • a definition with a nested $ref;
  • a definition with a nested $ref, validated against a sub schema (rootElementPath).

The last two fail on main, and the first two pass there too.

yarn tsc and the full yarn test pass locally on Node 22 (169 test suites and 3653 tests passed, 1 suite and 61 tests skipped), and ESLint and Prettier pass on the changed files. The changed lines are covered.

Manual test in localtest with a copy of one of our apps (Altinn.App 8.12.11), where Virksomhet.epost and Innsender.kontaktInfo.epost both have "errorMessage": "Epost.feilmelding", and only KontaktInfo has a nested $ref. The local builds were loaded through localtest's frontendVersion cookie:

  • app-frontend 4 from the CDN and main (cd18b44) built locally: the custom message under Virksomhet.epost, «Feil format eller verdi» under Innsender.kontaktInfo.epost.
  • This branch built locally: the custom message under both.

Summary by CodeRabbit

  • Bug Fixes
    • Custom error messages now display correctly for invalid phone numbers in root fields, schema definitions, and nested references. This keeps the configured message associated with the affected contact.phoneNumber field, including when validation uses a referenced subschema.

…tion has a nested $ref

SchemaValidation looked up the failing field's schema from error.schemaPath.
When a referenced definition itself contains a $ref, AJV compiles it
separately and reports a schemaPath relative to that definition, so the
lookup against the root schema found nothing and the user got the
standard text instead of the custom error message.

Use error.parentSchema, which AJV sets with verbose: true and which is
the schema that failed in every case.
@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: a59aab58-989e-4d9f-86e9-95d12ddbfdda
📥 Commits

Reviewing files that changed from the base of the PR and between 747ba71 and 39d6264.

📒 Files selected for processing: 1
  • src/features/validation/schemaValidation/SchemaValidation.tsx
🚧 Files skipped from review as they are similar to previous changes: 1
  • src/features/validation/schemaValidation/SchemaValidation.tsx

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

SchemaValidation now uses AJV’s error.parentSchema to identify the failing field’s schema. New tests check custom error-message reporting for root properties, definitions, and nested references.

Changes: Custom schema error messages

Layer / File(s) Summary
Field schema lookup and coverage
src/features/validation/schemaValidation/SchemaValidation.tsx, src/features/validation/schemaValidation/SchemaValidation.test.tsx
SchemaValidation reads the failing field schema from error.parentSchema instead of resolving it through error.schemaPath. Parameterized tests check the phoneNumber.error key across four schema configurations.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related issues

Suggested reviewers: bjosttveit

Merge Risk: ⚪ Minimal · up to 39d62

The reviewed change has no identified issue that needs resolution before merging.

Pre-merge checks: Passed 5
Check name Status Explanation
Title check Passed The title clearly identifies the validation fix and the nested $ref case addressed by the pull request.
Description check Passed The description is complete. It explains the issue, implementation, scope, related issue, manual and automated verification, test coverage, and repository checklist status.
Linked Issues check Passed Issue #4389 requires the field's custom errorMessage for validation failures in definitions with nested $ref, including rootElementPath validation. SchemaValidation.tsx now reads `error.parent…
Out of Scope Changes check Passed The changes are limited to the validation lookup and focused unit tests. The tests directly cover issue #4389. The separate case of errorMessage beside a $ref remains unchanged, as stated in the P…
Docstring Coverage Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 1 functions across 2 files.
Full details: Linked Issues check

Explanation

Issue #4389 requires the field's custom errorMessage for validation failures in definitions with nested $ref, including rootElementPath validation. SchemaValidation.tsx now reads error.parentSchema.errorMessage instead of resolving error.schemaPath against the root schema. The table test covers root properties, definitions without and with nested $ref, and a nested $ref with a sub-schema.

Full details: Out of Scope Changes check

Explanation

The changes are limited to the validation lookup and focused unit tests. The tests directly cover issue #4389. The separate case of errorMessage beside a $ref remains unchanged, as stated in the PR scope.

✨ Finishing Touches: 💡 1
🛠️ Fix failing CI checks: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@Bjarnisan
Bjarnisan marked this pull request as ready for review October 22, 2026 08:18
@Bjarnisan

Copy link
Copy Markdown
Contributor Author

could someone re-run the failed cypress job? pretty sure it's the TT02 enviroment being slow and not this change

all the steps in "Deeply linked hidden with component lookups" passed. it failed in the global afterEach => waitUntilSaved timed out on the last save to TT02
the retry then timed out on POST /instances before the test even started (screenshots in the external-logs artifact)

same commit (747ba71) passed the full cypress run earlier today in run 39701849548

also needs labels for check-label. kind/bug I think, backport or backport-ignore is your call

@olemartinorg olemartinorg added squad/utforming Issues that belongs to the named squad. and removed squad/utforming Issues that belongs to the named squad. labels Oct 26, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Custom errorMessage in the data model is ignored when the definition contains a $ref

2 participants