Skip to content

[Streams] Add field descriptions and unmapped field type#250785

Closed
flash1293 wants to merge 58 commits intoelastic:mainfrom
flash1293:ralph/issue-35
Closed

[Streams] Add field descriptions and unmapped field type#250785
flash1293 wants to merge 58 commits intoelastic:mainfrom
flash1293:ralph/issue-35

Conversation

@flash1293
Copy link
Copy Markdown
Contributor

@flash1293 flash1293 commented Jan 28, 2026

🍒 Summary

Adds support for field descriptions and a new unmapped field type in Streams, allowing users to document fields without creating Elasticsearch mappings.

Closes https://github.com/elastic/streams-program/issues/765

Summary

Addresses reviewer feedback in elastic/kibana#250785:

  • UI: Editing a field description no longer re-runs the schema sample preview simulation on every keystroke.
  • Classic streams: Allow persisting description-only overrides for dynamic fields via ingest.classic.field_overrides without attempting invalid Elasticsearch mapping updates.
  • UI (Classic streams): In the schema editor status filter dropdown, show Dynamic (not Unmapped) for Classic streams.

Also keeps the earlier hardening around typeless doc-only overrides (reject type: 'unmapped' in ingest upserts; ignore doc-only definitions for simulation).

Changes

  • UI: Make the preview simulation request depend only on mapping-affecting field definition config (exclude description), so description edits don’t refetch.
  • Server (Classic streams): Filter field_overrides before ES mapping dry-run / update:
    • Drop typeless metadata-only overrides (no mapping type)
    • Strip description from mapping payloads
    • Skip mapping actions entirely when there are no mapping-affecting overrides
  • UI (Classic streams): Stream-type-aware status filter label: underlying unmapped key renders as Dynamic for Classic.

Test plan

  • yarn test:jest x-pack/platform/plugins/shared/streams/server/lib/streams/state_management/streams/classic_stream.test.ts
  • yarn test:jest x-pack/platform/plugins/shared/streams_app/public/components/data_management/schema_editor/flyout/sample_preview_table.test.tsx
  • yarn test:jest x-pack/platform/plugins/shared/streams_app/public/components/data_management/schema_editor/filters/status_filter_group.test.tsx
  • yarn test:type_check --project x-pack/platform/plugins/shared/streams/tsconfig.json
  • yarn test:type_check --project x-pack/platform/plugins/shared/streams_app/tsconfig.json

- Add optional `description` property to field definitions for documenting fields
- Add new `unmapped` field type that allows describing fields without creating ES mappings
- Store descriptions as metadata (not sent to Elasticsearch)
- Skip `unmapped` fields in mapping generation (like `system` fields)
- Add description editing in schema editor flyout for both wired and classic streams
- Add description column to schema table with tooltip support
- Add comprehensive tests for schema validation, mapping generation, and UI utilities

Co-authored-by: Cursor <cursoragent@cursor.com>
@elasticmachine
Copy link
Copy Markdown
Contributor

elasticmachine commented Jan 28, 2026

🤖 Jobs for this PR can be triggered through checkboxes. 🚧

ℹ️ To trigger the CI, please tick the checkbox below 👇

  • Click to trigger kibana-pull-request for this PR!
  • Click to trigger kibana-deploy-project-from-pr for this PR!
  • Click to trigger kibana-deploy-cloud-from-pr for this PR!
  • Click to trigger kibana-entity-store-performance-from-pr for this PR!
  • Click to trigger kibana-storybooks-from-pr for this PR!

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph I didn't think this through fully in terms of the UI:

  • The confirm changes modal says "type unmapped", but status "mapped". It should be filtered out from that view
  • When setting the description on the schema tab, you need to select "map field" - this is weird. Instead it should be a different context menu action "edit description" to set the description in a different flyout. This should also be possible for inherited fields, not just fields on the current "level"
  • The table doesn't show the description, there should be a column for it

- Filter unmapped type fields from confirm changes modal (they don't affect ES mappings)
- Add "Edit description" action for all field statuses (mapped, unmapped, inherited)
- Add description column to default table columns
- Add tests for confirm modal filtering logic
@flash1293
Copy link
Copy Markdown
Contributor Author

Addressed the UI feedback:

Issue 1: Confirm changes modal showing unmapped type fields

  • Modified getChanges() in schema_changes_review_modal.tsx to filter out fields with type === 'unmapped'
  • These documentation-only fields don't affect ES mappings, so they no longer appear in the confirm modal

Issue 2: "Edit description" action

  • Created new EditDescriptionFlyout component (flyout/edit_description_flyout.tsx) - a simple flyout for editing just the description
  • Added "Edit description" action to all field statuses in field_actions.tsx:
    • Mapped fields: View, Edit, Edit description, Unmap
    • Unmapped status fields: View, Map, Edit description
    • Inherited fields: View, Edit description
  • For inherited fields, shows a callout explaining that setting a description creates an override in the current stream

Issue 3: Description column not visible by default

  • Added 'description' to DEFAULT_TABLE_COLUMN_NAMES in constants.ts

Testing

  • Added unit tests for the confirm modal filtering logic (schema_changes_review_modal.test.ts)
  • All existing tests pass
  • TypeScript and lint validation pass

Written by cursor, wait for @flash1293 to chime in

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph

  • the UI in the schema tab looks good, but saving with only unmapped fields is not actually saving them - it just sends fields: {} in the request to the server. Make sure that unmapped fields are only filtered out for display when it's about mapping only, not for actually making requests.
  • When in the "Modified fields" tab in processing, goign through the "Edit description" flyout on an unmapped field seems to not retain the description. We need to make sure the description is kept around

I think in both places we need to trace through the control flow and make sure to not filter out the unmapped fields in the wrong places, since we need to keep the description around

When editing a description on an unmapped field:
- EditDescriptionFlyout now sets status to 'mapped' and type to 'unmapped'
  (documentation-only) so the field gets saved to the stream definition
- DetectedFieldsEditor now checks for meaningful updates on unmapped fields
  and calls mapField() instead of unmapField() to preserve descriptions

Added comprehensive tests for EditDescriptionFlyout covering mapped,
unmapped, and inherited field scenarios.

Fixes the issue where saving unmapped fields sent `fields: {}` and
descriptions were lost when editing from the "Modified fields" tab.

Co-authored-by: Cursor <cursoragent@cursor.com>
@flash1293
Copy link
Copy Markdown
Contributor Author

Fixed both issues reported in #250785 (comment)

Root cause: When editing a description on an unmapped field, the EditDescriptionFlyout was preserving status: 'unmapped', which caused:

  1. Schema tab issue: Field was filtered out by buildSchemaSavePayload() (filters by status === 'mapped') → sent fields: {} to server
  2. Processing tab issue: detected_fields_editor.tsx called unmapField() for unmapped fields which recreated the field without the description

Fixes:

  • EditDescriptionFlyout: When saving on an unmapped field, now sets status: 'mapped' and type: field.type ?? 'unmapped' (documentation-only)
  • detected_fields_editor.tsx: Added check for meaningful updates (description or type: 'unmapped') on unmapped fields - calls mapField() instead of unmapField() to preserve the updates

Tests added:

  • edit_description_flyout.test.tsx with 7 tests covering mapped, unmapped, and inherited field scenarios

Written by cursor, wait for @flash1293 to chime in

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph

  • The "Inherited field override" modal has a broken icon
  • When setting a description on an inherited field, it shows in the table but when clicking save it's not sent to the server and then disappears
  • In the table "type: unmapped" fields with description are shown different than actually unmapped fields that are not mentioned in the definition:
    • In the "Type" column the former shows "Unmapped", while the latter shows ---- - it should always be -----
    • In the "status" column the former shows "Mapped", which is very confusing, it should show "Unmapped" like the latter
  • For wired streams it's showing an alias for the type: unmapped field, this doesn't make any sense, unmapped fields don't have an automatic alias

- Fix broken icon in "Inherited field override" callout (iInCircle → info)
- Fix inherited field description not being saved (set status to 'mapped')
- Fix inconsistent display of type: 'unmapped' fields (show EMPTY_CONTENT for type, 'unmapped' for status)
- Fix alias showing for unmapped fields (handled by type check)
- Update tests for inherited field handling
- Add tests for unmapped field behavior in getDefinitionFields

Co-authored-by: Cursor <cursoragent@cursor.com>
@flash1293
Copy link
Copy Markdown
Contributor Author

Fixed the issues reported in the review comment:

1. Broken icon in "Inherited field override" modal

  • Changed iconType="iInCircle" to iconType="info" in edit_description_flyout.tsx

2. Inherited field description not being saved

  • Updated handleSave in edit_description_flyout.tsx to set status: 'mapped' for inherited fields when saving description
  • This ensures the field gets included in buildSchemaSavePayload() which only sends status === 'mapped' fields

3. Inconsistent display of type: 'unmapped' fields

  • Updated schema_editor_table.tsx to show ---- (EMPTY_CONTENT) in the Type column when field.type === 'unmapped'
  • Added displayStatus variable that overrides status to 'unmapped' when field.type === 'unmapped'

4. Alias showing for unmapped fields

  • Fixed by the same change - returning EMPTY_CONTENT for the type column prevents the FieldType component (which renders aliases) from being rendered

Tests added:

  • Updated existing inherited field test to verify correct behavior
  • Added 2 new tests for getDefinitionFields to document unmapped field handling

Written by cursor, wait for @flash1293 to chime in

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph

  • It's still showing an alias-like entry in the list. E.g. if I have attributes.abc.def unmapped with a description, it will also show abc.def with the same description. It shouldn't do that, it shouldn't show this row at all.
  • On the schema tab something is wrong with the logic that shows the footer bar to save changes - if you have descriptions, it's always showing
  • Implicitly, this added the ability to unmap a field that is mapped on the parent (by setting type: unmapped). This shouldn't be allowed. Make sure it's part of the validation of the wired streams and also the "unmap/map field" context menu entries are not shown in the schema tab
  • If a field has just a description, there shouldn't be an "Unmap field" context menu action
  • If a field has a description, there should be a "Clear description" context menu action

- Fix alias entries for unmapped fields: Skip fields with type: 'unmapped'
  in createAliasesForNamespacedFields since they're documentation-only
- Fix footer bar always showing: Use isFieldUncommitted for consistent
  comparison in pendingChangesCount calculation
- Fix validation for unmapping parent-mapped fields: Add validation in
  validateAncestorFields to prevent setting type: 'unmapped' on fields
  mapped in parent; hide map/unmap actions for inherited fields in UI
- Fix "Unmap field" for description-only fields: Don't show action when
  field.type === 'unmapped' since there's nothing to unmap
- Add "Clear description" action: New context menu action to remove
  description from fields that have one

Includes comprehensive test coverage for all changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@flash1293
Copy link
Copy Markdown
Contributor Author

Addressed all feedback items from the review comment:

1. Fixed alias-like entries for unmapped fields
Modified createAliasesForNamespacedFields in logs_layer.ts to skip fields with type: 'unmapped'. Documentation-only fields don't have ES mappings, so aliases shouldn't be created for them (e.g., attributes.abc.def unmapped no longer creates a fake abc.def alias entry).

2. Fixed footer bar always showing with descriptions
The pendingChangesCount calculation in use_schema_fields.ts was using a different comparison than isFieldUncommitted. Updated to use isFieldUncommitted for consistency, which properly handles field defaults like additionalParameters: {}, format: undefined, etc.

3. Fixed ability to unmap parent-mapped fields

  • Added server-side validation in validateAncestorFields to throw MalformedFieldsError when attempting to set type: 'unmapped' on a field that has a real type in the parent stream
  • Updated field_actions.tsx to hide "Unmap field" for mapped fields that override inherited fields, and hide "Map field"/"Map as geo field" for unmapped fields that have an inherited counterpart

4. Fixed misleading "Unmap field" for description-only fields
Added condition to hide "Unmap field" action when field.type === 'unmapped' since these are documentation-only entries with no actual ES mapping to unmap.

5. Added "Clear description" context menu action
Added a new "Clear description" action that appears for fields with a description, allowing users to remove the description entirely.

Test coverage added:

  • logs_layer.test.ts: Test for unmapped fields not creating aliases
  • validate_fields.test.ts: Tests for parent-mapped field validation
  • field_actions.test.tsx: Comprehensive tests for all context menu action scenarios
  • use_schema_fields.test.tsx: Regression test for pending changes count

Written by cursor, wait for @flash1293 to chime in

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph

and hide "Map field"/"Map as geo field" for unmapped fields that have an inherited counterpart

Actually, it should be allowed this way - you should be able to have type: unmapped on let's say logs.abc, then set a type: keyword for it on logs.abc.def, not just the other way around. Make sure it works like that

Fixed the field inheritance logic to allow child streams to map fields
when the parent has type: 'unmapped' (documentation-only).

Changes:
- field_actions.tsx: Only hide "Map field"/"Map as geo field" when
  parent has a REAL type (not 'unmapped')
- validate_fields.ts: Allow setting a real type when parent has
  type: 'unmapped'
- Added tests for both client-side and server-side changes

Co-authored-by: Cursor <cursoragent@cursor.com>
@flash1293
Copy link
Copy Markdown
Contributor Author

Addressed the feedback from the review comment:

Issue: The previous implementation hid "Map field"/"Map as geo field" for ANY unmapped field that has an inherited counterpart. But it should only hide these actions when the parent has a real ES mapping (keyword, date, etc.), not when the parent has type: 'unmapped'.

Expected behavior: You should be able to have type: unmapped on logs.abc, then set type: keyword for it on logs.abc.def - the child should be able to add a real mapping when the parent only has documentation.

Fixes:

  1. Client-side (field_actions.tsx):

    • Changed isMappedInParent check to hasRealMappingInParent that excludes type: 'unmapped'
    • "Map field" and "Map as geo field" now show when parent has type: 'unmapped'
    • "Unmap field" still hidden when any inherited entry exists (to prevent removing documentation)
  2. Server-side (validate_fields.ts):

    • Updated the "incompatible type" check to allow any type when parent has type: 'unmapped'
    • Child streams can now set real types (keyword, date, etc.) on fields that are documented-only in parents

Tests added:

  • field_actions.test.tsx: Test for "Map field" showing when parent has type: 'unmapped'
  • validate_fields.test.ts: Tests for allowing real types when parent has type: 'unmapped'

Written by cursor, wait for @flash1293 to chime in

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph

  • When I'm on the schema tab an a mapped inherited field has a description, the bottom bar for saving is always showing even though I didn't change anything. This needs to be fixed
  • Also, when a field has descriptions on multiple layers of the hierarchy, it shows multiple times, I guess because it's part of the inherited_fields and stream.ingest.wired.field at the same time, we need to consolidate here (the more specific description should win out)

- Fix duplicate fields showing when a mapped field overrides an inherited field
- Fix save bar showing incorrectly on initial load due to field comparison issues
- Filter out description property before passing fields to ES simulation to prevent mapping errors
- Add regression tests for deduplication and pending changes behavior

Co-authored-by: Cursor <cursoragent@cursor.com>
@flash1293
Copy link
Copy Markdown
Contributor Author

Fixed the issues mentioned in the review comment:

Issue 1: Save bar showing on initial load with inherited field descriptions

  • Root cause: When a field existed in both inherited_fields and wired.fields (e.g., when overriding a parent field to add a description), it appeared twice in the field list
  • The isFieldUncommitted function compared the 'mapped' version against a potentially different 'inherited' version in stored fields

Issue 2: Duplicate fields showing when inherited and mapped

  • Root cause: getDefinitionFields was combining fields from both sources without deduplication
  • Fix: Added deduplication logic to filter out inherited fields that already exist in mapped fields (more specific wins)

Issue 3: ES simulation failing on keyword fields with descriptions

  • Root cause: description property was included in the spread when building ES mapping properties, but ES doesn't recognize it
  • Fix: Destructure and exclude description when building propertiesForSimulation

Changes:

  • Modified getDefinitionFields() in use_schema_fields.ts to deduplicate fields
  • Modified ES simulation route to filter out description before passing to ES
  • Added regression tests for both deduplication and pending changes behavior

Written by cursor, wait for @flash1293 to chime in

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph

  • Merge the "edit description" context action into the main "map field" flyout, and change the name from "Map field" to "Edit field". It should be possible to also pick "Unmapped" as field type, but if that's the case, you can only edit the description, nothing else
  • If you "edit field" on an inherited field, you should only be able to change the description, nothing else

Remove the separate "Edit description" flyout and route edits through the main SchemaEditorFlyout.
When editing inherited fields or selecting type "unmapped", restrict the UI and staging payload to description-only changes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@flash1293
Copy link
Copy Markdown
Contributor Author

Addressed the latest review feedback (unify the edit UX + description-only restrictions):

  • Removed the separate "Edit description" context action/flyout and routed everything through the main "Edit field" (SchemaEditorFlyout).
  • Renamed "Map field" → "Edit field".
  • Added description-only mode in the unified flyout:
    • Editing an inherited field: only description can be changed (type/format/advanced options/simulation hidden/disabled).
    • Selecting type = unmapped: only description can be changed.
  • Kept "Clear description" behavior.

Also added/updated tests around the unified flyout behavior (schema_editor_flyout.test.tsx).

Commit: 9c7ecc186d2b

@flash1293
Copy link
Copy Markdown
Contributor Author

Addressed the feedback from #250785 (comment)

Problem: When users select "Unmapped" type with a description in wired streams, the system was still trying to run a field simulation with type: 'unmapped', which fails because this type represents a description-only override.

Changes:

  • Updated the mappedFields filter in schema_changes_review_modal.tsx to exclude type === 'unmapped' from the fields simulation call
  • Updated getMappingAffectingConfig() in getChanges() to return null for type === 'unmapped' fields, ensuring the confirmation modal isn't shown for description-only changes
  • Added 5 new test cases for type: 'unmapped' handling scenarios

Behavior after changes:

  • Fields with type: 'unmapped' are not sent to the fields_simulation API
  • The confirmation modal is skipped entirely if all changes are description-only (type: 'unmapped')
  • When there's a mix of real mapping changes and description-only changes, only the real mapping changes are simulated

Written by cursor, wait for @flash1293 to chime in

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph Update this PR with upstream/main and fix all conflicts.

Also there still seems to be an issue in the state management:

  • GO to schema tab of wired stream
  • Select unmapped field
  • Select "unmapped" as type
  • Provide description
  • Save

POST /api/streams/logs.linux/_ingest errors because the type is literally sent as such:

{
    "lifecycle": {
        "inherit": {}
    },
    "processing": {
        "steps": []
    },
    "settings": {},
    "wired": {
        "fields": {
            "attributes.process.id": {
                "type": "unmapped",
                "description": "This is a test"
            }
        },
        "routing": []
    },
    "failure_store": {
        "inherit": {}
    }
}

We should remove "type: unmapped" from here as well - if the user picks it from the list, it just sets the type to undefined.

There is another issue - when mapping a field properly and adding a description and saving, the existing description (made on the current stream) of an inherited field is removed - it's probably filtered out when the PUT request is assembled. We need to make sure these are preserved. Example:

  • Go to logs.android
  • Set a description on trace_id
  • Save - everything works
  • Map a new field and add a description
  • Save
  • New field is saved, description on trace_id is lost

flash1293 and others added 2 commits February 25, 2026 10:32
Resolves merge conflicts in:
- generate_layer.test.ts: Keep both doc-only field tests from PR and root stream mapping tests from upstream
- logs_layer.ts: Use upstream's re-export pattern; add doc-only field filtering to logs_otel_layer.ts
- simulation_handler.ts: Merge imports from both branches
- route.ts: Merge imports from both branches
- basic.ts: Keep description-only override test from PR, update to use logs.otel root stream

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit addresses two bugs in the schema editor:

1. Fix 'unmapped' type being sent to server
   - When selecting "Unmapped" from the type dropdown, the value was being
     sent as `type: 'unmapped'` which caused server errors
   - Now treats 'unmapped' selection as undefined type, creating a doc-only
     override instead of a mapped field
   - Added safety check in convertToFieldDefinitionConfig to throw if
     'unmapped' type ever reaches that function

2. Fix inherited field descriptions being lost on save
   - Description overrides on inherited fields were being merged into the
     inherited field view with status='inherited', then filtered out when
     building the save payload
   - Now detects inherited fields with description overrides by comparing
     against the original inherited description, and preserves them in the
     save payload

Added unit tests for both fixes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@flash1293
Copy link
Copy Markdown
Contributor Author

Changes Made

I've updated this PR with upstream/main and fixed the two bugs reported:

Bug Fix 1: 'unmapped' type being sent to server

When a user selected "Unmapped" from the type dropdown for an unmapped field and provided a description, the type was being sent as type: 'unmapped' which caused a server error.

Fix: In flyout/index.tsx, when staging a field:

  • If the user selects "Unmapped" (rawType === 'unmapped'), treat it as undefined type
  • This creates a doc-only override (description only) instead of a mapped field with invalid type
  • Added a safety check in convertToFieldDefinitionConfig to throw if 'unmapped' type ever reaches that function

Bug Fix 2: Inherited field descriptions being lost on save

When an inherited field had a description override on the current stream, the description was being merged into the inherited field view (keeping status: 'inherited'). Then in buildSchemaSavePayload, only status === 'mapped' or status === 'unmapped' && hasDescription fields were persisted, causing inherited field description overrides to be lost.

Fix: In buildSchemaSavePayload in utils.ts:

  • Built a map of inherited field descriptions from definition.inherited_fields
  • Added a new branch: for status === 'inherited' fields with non-empty descriptions, compare against the inherited description
  • If the description differs from the inherited one, it's a doc-only override on THIS stream and needs to be persisted

Unit Tests Added

  • convertToFieldDefinitionConfig throws for type: 'unmapped'
  • buildSchemaSavePayload preserves description overrides on inherited fields
  • buildSchemaSavePayload does NOT persist inherited field description if it matches the inherited description

@flash1293
Copy link
Copy Markdown
Contributor Author

/ci

@flash1293
Copy link
Copy Markdown
Contributor Author

/ci-ralph

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph check the test failures of build 401306 and fix them

Build URL: https://buildkite.com/elastic/kibana-pull-request/builds/401306

Use ci/bk-build-info.sh 401306 to fetch detailed build failure information.

This commit fixes the TypeScript errors from build 401306:

1. Added 'unmapped' to SchemaFieldType - The UI treats 'unmapped' as a
   pseudo-type for description-only fields in wired streams, but it
   wasn't included in the type definition.

2. Fixed FieldType component - Updated to use FieldTypeOption from
   constants instead of FieldDefinitionConfig['type'] to properly
   include the 'unmapped' pseudo-type.

3. Fixed typeSupportsFormat function - Updated to accept SchemaFieldType
   instead of FieldDefinitionConfig['type'].

4. Fixed logs_otel_layer.ts - Added null check for target field type
   when creating inherited fields to handle doc-only fields.

5. Fixed validate_fields.test.ts - Added missing 'streamName' parameter
   to three test cases.

6. Fixed field_summary.tsx - Removed unused EuiSpacer import.

7. Fixed detected_fields_editor.tsx - Removed dead code branch that
   was handling typeless mapped fields (MappedSchemaField always has
   a type by definition).

8. Fixed utils.test.ts - Updated test assertions to properly narrow
   the IngestUpsertRequest union type.

9. Fixed stream_enrichment_state_machine/utils.test.ts - Added missing
   create_snapshot_repository privilege to test fixture.

Made-with: Cursor
@flash1293
Copy link
Copy Markdown
Contributor Author

Fixed TypeScript errors from Build 401306

Addressed all the TypeScript errors that were causing the Check Types step to fail.

Root Cause

The code introduced 'unmapped' as a UI pseudo-type for description-only fields in wired streams, but this type wasn't properly added to SchemaFieldType. This caused cascade type errors across multiple components.

Changes Made

  1. types.ts - Added 'unmapped' to SchemaFieldType with documentation clarifying it's a pseudo-type for UI purposes only

  2. field_type.tsx - Updated component to use FieldTypeOption instead of FieldDefinitionConfig['type'] to properly include the unmapped pseudo-type

  3. field_form_format.tsx - Updated typeSupportsFormat() to accept SchemaFieldType instead of FieldDefinitionConfig['type']

  4. field_summary.tsx - Removed unused EuiSpacer import

  5. logs_otel_layer.ts - Added null check for target field type when creating inherited fields, to handle doc-only fields gracefully

  6. validate_fields.test.ts - Added missing streamName parameter to three test cases

  7. detected_fields_editor.tsx - Removed dead code branch that was handling typeless mapped fields (since MappedSchemaField always has a type by definition)

  8. utils.test.ts - Updated test assertions to properly narrow the IngestUpsertRequest union type

  9. stream_enrichment_state_machine/utils.test.ts - Added missing create_snapshot_repository privilege to test fixture

All type checks and tests pass locally.

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph check the test failures of build 401368 and fix them

Build URL: https://buildkite.com/elastic/kibana-pull-request/builds/401368

Use ci/bk-build-info.sh 401368 to fetch detailed build failure information.

Replace `as any` casts with properly typed NamedFieldDefinitionConfig
arrays to satisfy @typescript-eslint/no-explicit-any rule.

Made-with: Cursor
@flash1293
Copy link
Copy Markdown
Contributor Author

Fixed Build 401368 Linting Errors

The build failed due to 5 @typescript-eslint/no-explicit-any ESLint errors in x-pack/platform/plugins/shared/streams/server/routes/internal/streams/schema/route.test.ts.

Root cause: The test file was using as any type assertions to cast test data arrays.

Fix: Replaced as any casts with properly typed NamedFieldDefinitionConfig[] arrays. The test data already conforms to the correct union type from @kbn/streams-schema, so no changes to the test logic were needed - just explicit typing.

All local validations pass:

  • ESLint: ✅
  • Jest tests: ✅ (5/5 passing)
  • TypeScript: ✅

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph check the test failures of build 401409 and fix them

Build URL: https://buildkite.com/elastic/kibana-pull-request/builds/401409

Use ci/bk-build-info.sh 401409 to fetch detailed build failure information.

1. FTR test failure: Changed stream name from 'logs' to 'logs.otel' in
   the "Ignores typeless (description-only) field definitions" tests.
   After the upstream merge that split logs into logs.otel/logs.ecs,
   the 'logs' root stream no longer exists as a standalone entity.

2. Jest test failure: Updated add_field_flyout tests to reflect the
   new behavior where wired streams allow description-only fields
   without a type. Added a new test for classic streams that still
   require a type selection.

3. Added unit tests for namedFieldDefinitionConfigSchema to ensure
   description-only field definitions are properly validated.

Made-with: Cursor
@flash1293
Copy link
Copy Markdown
Contributor Author

Fixed Build 401409 Test Failures

Addressed all test failures from build 401409:

1. FTR Test Failure: "Ignores typeless (description-only) field definitions"

Root cause: After the upstream merge (commit 5d38e2b) that split the logs endpoint into logs.ecs and logs.otel, the test was still using name: 'logs' as the stream name. The logs root stream no longer exists as a standalone entity - only logs.otel and logs.ecs exist after enabling streams.

Fix: Changed stream name from 'logs' to 'logs.otel' in the FTR tests for description-only field definitions.

2. Jest Test Failure: "disables the Add field button when field name is valid but type is not selected"

Root cause: This PR introduced the ability for wired streams to have description-only field overrides (without a type). The test expected the Add field button to be disabled when no type is selected, but this is now valid behavior for wired streams.

Fix:

  • Updated the test to expect the button to be enabled for wired streams (since description-only fields are allowed)
  • Added a new test for classic streams that verifies the button is still disabled when no type is selected (since classic streams require a type)

3. Added Unit Tests for namedFieldDefinitionConfigSchema

Added tests to ensure the schema properly validates description-only field definitions with just a name and description property.

Written by cursor, wait for @flash1293 to chime in

@elasticmachine
Copy link
Copy Markdown
Contributor

elasticmachine commented Feb 26, 2026

💔 Build Failed

Failed CI Steps

Test Failures

  • [job] [logs] FTR Configs #39 / apis Streams Endpoints Streams inheritance - description-only overrides does not persist type for description-only overrides and keeps inherited mappings dynamic
  • [job] [logs] FTR Configs #39 / apis Streams Endpoints Streams inheritance - description-only overrides does not persist type for description-only overrides and keeps inherited mappings dynamic
  • [job] [logs] Jest Integration Tests #13 / scripts/generate_plugin builds a generated plugin into a viable archive
  • [job] [logs] FTR Configs #134 / Serverless Observability - Deployment-agnostic Streams API integration tests Streams Endpoints Streams inheritance - description-only overrides does not persist type for description-only overrides and keeps inherited mappings dynamic

Metrics [docs]

‼️ ERROR: no builds found for mergeBase sha [8500782]

History

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph check the test failures of build 401479 and fix them

Build URL: https://buildkite.com/elastic/kibana-pull-request/builds/401479

Use ci/bk-build-info.sh 401479 to fetch detailed build failure information.

The 'logs' root stream no longer exists after the upstream merge that
split it into 'logs.ecs' and 'logs.otel'. Updated the test to fork from
'logs.otel' instead.

Made-with: Cursor
@flash1293
Copy link
Copy Markdown
Contributor Author

Fixed Build 401479 Test Failure

Root cause: The description_only_inheritance.ts test was trying to fork from 'logs', but after the upstream merge that split the logs endpoint into logs.ecs and logs.otel, the 'logs' root stream no longer exists as a standalone entity.

Fix: Updated the test to fork from 'logs.otel' instead of 'logs', and changed the parent stream name from logs.descriptiononlyparent to logs.otel.descriptiononlyparent for consistency with the new hierarchy.

This is the same fix pattern that was applied in commit 6a22c17 (Fix for Build 401409), but the stream name in the forkStream call was missed.

@flash1293
Copy link
Copy Markdown
Contributor Author

/ralph Please read through the changes on this PR so far and open a new clean draft PR with a proper summary for the eventual changes - on this PR too many things happened.

@flash1293
Copy link
Copy Markdown
Contributor Author

Created a clean PR with the squashed changes: #255136

The new PR has a comprehensive summary describing all features:

  • Field descriptions support
  • Documentation-only field overrides (typeless definitions)
  • UI improvements (Edit field action, Clear description, status filter)
  • Server-side validation
  • Classic streams support

This PR can be closed once #255136 is reviewed and merged.

Written by cursor, wait for @flash1293 to chime in

@flash1293 flash1293 closed this Feb 26, 2026
flash1293 added a commit that referenced this pull request Mar 11, 2026
…es (#255136)

## Summary

This PR adds support for field descriptions in Streams, allowing users
to document fields without creating Elasticsearch mappings
(documentation-only field overrides).

Closes elastic/streams-program#765

**This is a clean version of #250785**, which accumulated many iterative
changes during review.

## Features

### Field Descriptions
- Optional `description` property on field definitions for documenting
fields
- Description column in schema table with tooltip support
- "Edit field" flyout allows setting/editing descriptions for all field
types
- "Clear description" context menu action to remove descriptions
- Descriptions are stored as metadata and not sent to Elasticsearch

### Documentation-Only Field Overrides
- Fields can have descriptions without ES mappings (typeless
definitions)
- Child streams can add description overrides to inherited fields
- Doc-only overrides don't trigger ES mapping updates or simulation
- Confirm changes modal filters out doc-only changes

### UI Improvements
- Renamed "Map field" to "Edit field" since users can now add
descriptions without mapping
- "Edit field" action available for all field statuses (mapped,
unmapped, inherited)
- Status filter shows "Dynamic" (not "Unmapped") for Classic streams
- Field simulation excludes description-only changes from API calls

### Validation
- Server-side validation prevents invalid type overrides on inherited
fields
- UI hides "Unmap field" for fields that would conflict with parent
mappings
- Child streams can map fields when parent has doc-only field (no type)

### Classic Streams Support
- Classic streams can have descriptions on their fields, but it's _not_
possible to have description-only fields. It's necessary to map the
field explicitly if you want to provide a description.

## Test Plan

### Unit Tests
- `yarn test:jest
x-pack/platform/packages/shared/kbn-streams-schema/src/fields/index.test.ts`
- `yarn test:jest
x-pack/platform/plugins/shared/streams/server/routes/internal/streams/schema/route.test.ts`
- `yarn test:jest
x-pack/platform/plugins/shared/streams/server/routes/streams/ingest/validate_ingest_upsert.test.ts`
- `yarn test:jest
x-pack/platform/plugins/shared/streams_app/public/components/data_management/schema_editor/`

### Integration Tests
- `yarn test:ftr --config
x-pack/platform/test/api_integration_deployment_agnostic/configs/stateful/platform.serverless.config.ts`
(for streams inheritance tests)

### Type Checking
- `yarn test:type_check --project
x-pack/platform/plugins/shared/streams/tsconfig.json`
- `yarn test:type_check --project
x-pack/platform/plugins/shared/streams_app/tsconfig.json`

Made with [Cursor](https://cursor.com)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Field descriptions supported across the schema editor and save flows
* Documentation-only overrides (description without a mapping) and an
"Unmapped" field type for wired streams
* **Improvements**
* Description-aware inheritance so child streams can override
descriptions without forcing mappings
* UI updates: description column, editor, and flyout workflows; review
flow skips modal for description-only changes
* **Bug Fixes**
* Validation and mapping generation now ignore doc-only fields to
prevent incorrect mappings
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
sorenlouv pushed a commit that referenced this pull request Mar 17, 2026
…es (#255136)

## Summary

This PR adds support for field descriptions in Streams, allowing users
to document fields without creating Elasticsearch mappings
(documentation-only field overrides).

Closes https://github.com/elastic/streams-program/issues/765

**This is a clean version of #250785**, which accumulated many iterative
changes during review.

## Features

### Field Descriptions
- Optional `description` property on field definitions for documenting
fields
- Description column in schema table with tooltip support
- "Edit field" flyout allows setting/editing descriptions for all field
types
- "Clear description" context menu action to remove descriptions
- Descriptions are stored as metadata and not sent to Elasticsearch

### Documentation-Only Field Overrides
- Fields can have descriptions without ES mappings (typeless
definitions)
- Child streams can add description overrides to inherited fields
- Doc-only overrides don't trigger ES mapping updates or simulation
- Confirm changes modal filters out doc-only changes

### UI Improvements
- Renamed "Map field" to "Edit field" since users can now add
descriptions without mapping
- "Edit field" action available for all field statuses (mapped,
unmapped, inherited)
- Status filter shows "Dynamic" (not "Unmapped") for Classic streams
- Field simulation excludes description-only changes from API calls

### Validation
- Server-side validation prevents invalid type overrides on inherited
fields
- UI hides "Unmap field" for fields that would conflict with parent
mappings
- Child streams can map fields when parent has doc-only field (no type)

### Classic Streams Support
- Classic streams can have descriptions on their fields, but it's _not_
possible to have description-only fields. It's necessary to map the
field explicitly if you want to provide a description.

## Test Plan

### Unit Tests
- `yarn test:jest
x-pack/platform/packages/shared/kbn-streams-schema/src/fields/index.test.ts`
- `yarn test:jest
x-pack/platform/plugins/shared/streams/server/routes/internal/streams/schema/route.test.ts`
- `yarn test:jest
x-pack/platform/plugins/shared/streams/server/routes/streams/ingest/validate_ingest_upsert.test.ts`
- `yarn test:jest
x-pack/platform/plugins/shared/streams_app/public/components/data_management/schema_editor/`

### Integration Tests
- `yarn test:ftr --config
x-pack/platform/test/api_integration_deployment_agnostic/configs/stateful/platform.serverless.config.ts`
(for streams inheritance tests)

### Type Checking
- `yarn test:type_check --project
x-pack/platform/plugins/shared/streams/tsconfig.json`
- `yarn test:type_check --project
x-pack/platform/plugins/shared/streams_app/tsconfig.json`

Made with [Cursor](https://cursor.com)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
  * Field descriptions supported across the schema editor and save flows
* Documentation-only overrides (description without a mapping) and an
"Unmapped" field type for wired streams
* **Improvements**
* Description-aware inheritance so child streams can override
descriptions without forcing mappings
* UI updates: description column, editor, and flyout workflows; review
flow skips modal for description-only changes
* **Bug Fixes**
* Validation and mapping generation now ignore doc-only fields to
prevent incorrect mappings
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

backport:skip This PR does not require backporting Feature:Streams This is the label for the Streams Project release_note:skip Skip the PR/issue when compiling release notes Team:streams-program Team Label for Streams program v9.4.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants