From 7b0830a4cac36b7dd736824c8c59d465ce38aa73 Mon Sep 17 00:00:00 2001 From: Alexander Brown Date: Sat, 24 Jan 2026 16:27:42 -0800 Subject: [PATCH] fix: fallback to asset metadata/name when filename missing (#8302) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Summary Fix model node creation failing when `user_metadata.filename` is missing by falling back to `asset.metadata.filename` or `asset.name`. ## Changes - Add fallback chain for filename: `userMetadata.filename || validAsset.metadata?.filename || validAsset.name` ## Testing Manual testing with assets that have filename in different metadata locations. ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-8302-fix-fallback-to-asset-metadata-name-when-filename-missing-2f36d73d365081478299e2f2c1abde81) by [Unito](https://www.unito.io) --------- Co-authored-by: Amp --- .../utils/createModelNodeFromAsset.test.ts | 51 ++++++++++++++----- .../assets/utils/createModelNodeFromAsset.ts | 16 ++---- 2 files changed, 41 insertions(+), 26 deletions(-) diff --git a/src/platform/assets/utils/createModelNodeFromAsset.test.ts b/src/platform/assets/utils/createModelNodeFromAsset.test.ts index e8b12587b..cbc28f866 100644 --- a/src/platform/assets/utils/createModelNodeFromAsset.test.ts +++ b/src/platform/assets/utils/createModelNodeFromAsset.test.ts @@ -226,6 +226,30 @@ describe('createModelNodeFromAsset', () => { expect(result.success).toBe(true) expect(vi.mocked(app).canvas.graph!.add).toHaveBeenCalledWith(mockNode) }) + it('should fallback to asset.metadata.filename when user_metadata.filename missing', async () => { + const asset = createMockAsset({ + user_metadata: {}, + metadata: { filename: 'models/checkpoints/from-metadata.safetensors' } + }) + const mockNode = await createMockNode() + await setupMocks({ createdNode: mockNode }) + const result = createModelNodeFromAsset(asset) + expect(result.success).toBe(true) + expect(mockNode.widgets?.[0].value).toBe( + 'models/checkpoints/from-metadata.safetensors' + ) + }) + it('should fallback to asset.name when both filename sources missing', async () => { + const asset = createMockAsset({ + user_metadata: {}, + metadata: undefined + }) + const mockNode = await createMockNode() + await setupMocks({ createdNode: mockNode }) + const result = createModelNodeFromAsset(asset) + expect(result.success).toBe(true) + expect(mockNode.widgets?.[0].value).toBe('test-model.safetensors') + }) it('should add node to active subgraph when present', async () => { const asset = createMockAsset() const mockNode = await createMockNode() @@ -253,27 +277,28 @@ describe('createModelNodeFromAsset', () => { }) it.each([ { - case: 'missing user_metadata', - overrides: { user_metadata: undefined }, + case: 'missing user_metadata with no fallback', + overrides: { user_metadata: undefined, metadata: undefined, name: '' }, expectedCode: 'INVALID_ASSET' as const, - errorPattern: /missing required user_metadata/ - }, - { - case: 'missing filename property', - overrides: { user_metadata: {} }, - expectedCode: 'INVALID_ASSET' as const, - errorPattern: - /Invalid filename.*expected non-empty string, got undefined/ + errorPattern: /Invalid filename.*expected non-empty string/ }, { case: 'non-string filename', - overrides: { user_metadata: { filename: 123 } }, + overrides: { + user_metadata: { filename: 123 }, + metadata: undefined, + name: '' + }, expectedCode: 'INVALID_ASSET' as const, errorPattern: /Invalid filename.*expected non-empty string, got number/ }, { - case: 'empty filename', - overrides: { user_metadata: { filename: '' } }, + case: 'empty filename with no fallback', + overrides: { + user_metadata: { filename: '' }, + metadata: undefined, + name: '' + }, expectedCode: 'INVALID_ASSET' as const, errorPattern: /Invalid filename.*expected non-empty string/ } diff --git a/src/platform/assets/utils/createModelNodeFromAsset.ts b/src/platform/assets/utils/createModelNodeFromAsset.ts index b180a0a5d..dee53ef60 100644 --- a/src/platform/assets/utils/createModelNodeFromAsset.ts +++ b/src/platform/assets/utils/createModelNodeFromAsset.ts @@ -69,20 +69,10 @@ export function createModelNodeFromAsset( const validAsset = validatedAsset.data - const userMetadata = validAsset.user_metadata - if (!userMetadata) { - console.error(`Asset ${validAsset.id} missing required user_metadata`) - return { - success: false, - error: { - code: 'INVALID_ASSET', - message: 'Asset missing required user_metadata', - assetId: validAsset.id - } - } - } + const userMetadata = validAsset.user_metadata ?? {} - const filename = userMetadata.filename + const filename = + userMetadata.filename || validAsset.metadata?.filename || validAsset.name if (typeof filename !== 'string' || filename.length === 0) { console.error( `Asset ${validAsset.id} has invalid user_metadata.filename (expected non-empty string, got ${typeof filename})`