fix: fallback to asset metadata/name when filename missing (#8302)

## 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 <amp@ampcode.com>
This commit is contained in:
Alexander Brown
2026-01-24 16:27:42 -08:00
committed by GitHub
parent 4771565486
commit 7b0830a4ca
2 changed files with 41 additions and 26 deletions

View File

@@ -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/
}

View File

@@ -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})`