FlowiseAI/Flowise · error · Error

Unknown content ${JSON.stringify(content)}

Error message

Unknown content ${JSON.stringify(content)}

What it means

Thrown in _convertLangChainContentToPart (line 309) when a content block has NO 'type' field (and does not match the inline mimeType+data or functionCall shapes). It is the untyped fallback of the content dispatcher and includes the full JSON of the unrecognized block for diagnosis.

Source

Thrown at packages/components/nodes/chatmodels/ChatGoogleGenerativeAI/FlowiseChatGoogleGenerativeAI.ts:309

    } else if (
        content.type?.includes('/') &&
        content.type.split('/').length === 2 &&
        'data' in content &&
        typeof content.data === 'string'
    ) {
        return {
            inlineData: {
                mimeType: content.type,
                data: content.data
            }
        }
    } else if ('functionCall' in content) {
        return undefined
    } else {
        if ('type' in content) {
            throw new Error(`Unknown content type ${content.type}`)
        } else {
            throw new Error(`Unknown content ${JSON.stringify(content)}`)
        }
    }
}

export function convertMessageContentToParts(
    message: BaseMessage,
    isMultimodalModel: boolean,
    previousMessages: BaseMessage[],
    model?: string
): Part[] {
    if (ToolMessage.isInstance(message)) {
        const messageName = message.name ?? inferToolNameFromPreviousMessages(message, previousMessages)
        if (messageName === undefined) {
            throw new Error(
                `Google requires a tool name for each tool call response, and we could not infer a called tool name for ToolMessage "${message.id}" from your passed messages. Please populate a "name" field on that ToolMessage explicitly.`
            )
        }

View on GitHub (pinned to abe4a8601a)

Solutions

  1. Add a valid 'type' field to the content part (e.g., 'text', 'image_url', 'media').
  2. Ensure upstream serialization preserves the type discriminator.
  3. Sanitize the content array to drop or repair untyped parts before the Gemini call.

Example fix

// before (throws): { text: 'hello' }  // no type
// after:           { type: 'text', text: 'hello' }
Defensive patterns

Strategy: validation

Validate before calling

function hasTypeOrKnownShape(c: any): boolean {
  if (!c || typeof c !== 'object') return false
  if (typeof c.type === 'string') return true
  if ('functionCall' in c) return true
  if (typeof c.type === 'string' && typeof c.data === 'string') return true
  return false
}
for (const p of parts) {
  if (!hasTypeOrKnownShape(p)) throw new Error('content part missing a recognized discriminator (type/functionCall)')
}

Type guard

function isRecognizedContent(c: unknown): boolean {
  if (typeof c !== 'object' || c === null) return false
  const o = c as Record<string, unknown>
  return typeof o.type === 'string' || 'functionCall' in o
    || (typeof o.type === 'string' && typeof o.data === 'string')
}

Try / catch

try {
  return _convertLangChainContentToPart(part, isMultimodal)
} catch (e) {
  if (e instanceof Error && /Unknown content/.test(e.message)) {
    // drop the untyped part or tag it with a valid type
  }
  throw e
}

Prevention

When it happens

Trigger: A MessageContentComplex part lacks a 'type' key and is not a functionCall or inline-data shape.

Common situations: A raw object was placed in the content array without a type discriminator, or a serialization step stripped the type field.

Related errors


AI-assisted analysis of FlowiseAI/Flowise@abe4a8601a (2026-08-12). Data as JSON: /api/errors/8dbff6ff7c6e115b. Report an issue: GitHub.