Azure / Azure/azure-functions-host

BlobTrigger payload expression binding not working as expected

Open
#8,865 4 comments 0 reactions 0 assignees View on GitHub
breaking-change bug
Dominant language
C#
Stars
2k
Forks
482
Avg merge
2d 12h
Merged PRs (30d)
38

Description

When using a queue trigger binding with a blob input binding, the following example works as expected. In this example, we are able to parse the payload of `myBook` and use the `id` to evaluate `input-container/{id}.txt` to `input-container/1.txt`

QueueTrigger/index.js

```typescript
import { AzureFunction, Context } from "@azure/functions"

const queueTrigger:
AzureFunction = async function (context: Context, myBook: Book): Promise
{
context.log("Queue trigger function processed blob");
context.log("Book name:", myBook.name);
context.log("Book content:", context.bindings.myBlob);
};

type Book = {
id: string,
name: string,
}

export default queueTrigger;
```

function.json

```json
{
"bindings": [
{
"name": "myBook",
"type": "queueTrigger",
"direction": "in",
"queueName": "book-trigger",
"connection": "AzureWebJobsStorage"
},
{
"name": "myBlob",
"type": "blob",
"direction": "in",
"path": "input-container/{id}.txt",
"connection": "AzureWebJobsStorage"
}
],
"scriptFile": "../dist/QueueTrigger/index.js"
}
```

Trigger payload:

`{ "id": "1", "name": "mybook" }`

Output:

```log
[2022-10-25T22:58:17.636Z] Executing 'Functions.QueueTrigger' (Reason='New queue message detected on 'book-trigger'.', Id=e4545b2a-0fe5-4f08-aed5-705f24dfc2a3)
[2022-10-25T22:58:17.637Z] Trigger Details: MessageId: fd82d6a8-40dd-4275-a700-51c394e5bc1c, DequeueCount: 1, InsertedOn: 2022-10-25T22:58:15.000+00:00
[2022-10-25T22:58:17.857Z] Queue trigger function processed blob
[2022-10-25T22:58:17.858Z] Book name: mybook
[2022-10-25T22:58:17.858Z] Book content: hello world
[2022-10-25T22:58:17.884Z] Executed 'Functions.QueueTrigger' (Succeeded, Id=e4545b2a-0fe5-4f08-aed5-705f24dfc2a3, Duration=270ms)
```

**This behaviour is also expected to work for the BlobTrigger**

BlobTrigger/index.js

```typescript
import { AzureFunction, Context } from "@azure/functions"

const blobTrigger:
AzureFunction = async function (context: Context, myBook: Book): Promise
{
context.log("Blob trigger function processed blob")
context.log("Book name:", myBook.name);
context.log("Book content:", context.bindings.myBlob);
};

type Book = {
id: string,
name: string,
}

export default blobTrigger;
```

function.json

```json
{
"bindings": [
{
"name": "myBook",
"type": "blobTrigger",
"direction": "in",
"path": "book-trigger",
"connection": "AzureWebJobsStorage",
"dataType": "string"
},
{
"name": "myBlob",
"type": "blob",
"direction": "in",
"path": "input-container/{id}.txt",
"connection": "AzureWebJobsStorage",
"dataType": "string"
}
],
"scriptFile": "../dist/BlobTrigger/index.js"
}
```

Trigger payload (book.json)

`{ "id": "1", "name": "mybook" }`

Output

```log
[2022-10-25T22:58:52.738Z] Executing 'Functions.BlobTrigger' (Reason='New blob detected(LogsAndContainerScan): book-trigger/book.json', Id=a8c7a83f-f490-43a1-a6ca-955f554c19b5)
[2022-10-25T22:58:52.738Z] Trigger Details: MessageId: 3a6ad397-27ca-47d3-b012-5973cd36a039, DequeueCount: 1, InsertedOn: 2022-10-25T22:58:52.000+00:00, BlobCreated: 2022-10-25T21:39:49.000+00:00, BlobLastModified: 2022-10-25T22:58:42.000+00:00
[2022-10-25T22:58:52.785Z] Executed 'Functions.BlobTrigger' (Failed, Id=a8c7a83f-f490-43a1-a6ca-955f554c19b5, Duration=116ms)
[2022-10-25T22:58:52.785Z] System.Private.CoreLib: Exception while executing function: Functions.BlobTrigger. Microsoft.Azure.WebJobs.Host: No value for named parameter 'id'.
```

We should have seen is a similar result to what happened with the queue trigger:

```
Book name: mybook
Book content: hello world
```

Interestingly, when we remove the use of the blob input binding and just use a blob trigger by itself, still binding to a `Book`, instead of getting the payload as a `Book`, we get binary data (even if the data type is set to string):

```json
{
"bindings": [
{
"name": "myBook",
"type": "blobTrigger",
"direction": "in",
"path": "book-trigger",
"connection": "AzureWebJobsStorage",
"dataType": "string"
}
],
"scriptFile": "../dist/BlobTrigger/index.js"
}
```

```log
[2022-10-25T23:01:19.747Z] Executing 'Functions.BlobTrigger' (Reason='New blob detected(LogsAndContainerScan): book-trigger/book.json', Id=75277b64-3197-477c-afeb-044a30253ce6)
[2022-10-25T23:01:19.748Z] Trigger Details: MessageId: 9bd797ac-a7d8-477e-8516-791ae788c6c2, DequeueCount: 1, InsertedOn: 2022-10-25T23:01:19.000+00:00, BlobCreated: 2022-10-25T21:39:49.000+00:00, BlobLastModified: 2022-10-25T23:01:11.000+00:00
[2022-10-25T23:01:19.821Z] Blob trigger function processed blob
[2022-10-25T23:01:19.821Z] MyBook:
[2022-10-25T23:01:19.821Z] Book name: undefined
[2022-10-25T23:01:19.849Z] Executed 'Functions.BlobTrigger' (Succeeded, Id=75277b64-3197-477c-afeb-044a30253ce6, Duration=205ms)
```

We would expect to get a POCO as we have logic in the host [here](https://github.com/Azure/azure-functions-host/blob/91e0d11a13ee25debad1b5623088543c38a7d40d/src/WebJobs.Script/Description/Workers/WorkerFunctionInvoker.cs#L186) that pulls json values from the payload if it's a String. We can see this in action with the queue trigger example.

- [ ] The goal of this issue is to investigate why the payload binding expression is not working for the BlobTrigger

Contributor guide

Open the contributing guide

Research direction

Start with src/WebJobs.Script/Description/Workers/WorkerFunctionInvoker.cs at the referenced payload-binding logic, then compare the queue-trigger and BlobTrigger examples and their function.json bindings. Done means explaining and correcting why BlobTrigger payload values are unavailable to the input binding expression and why the trigger payload is received as binary data instead of the expected Book object.

Written by the indexing model from the issue text.

Assessment

Tech stack
azure, csharp, typescript
Domain
backend, cloud
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.