Repository: floci-io/floci (2026-04-15T16:03:28Z)

Issue:
[BUG] Lambda: UpdateFunctionCode missing LastUpdateStatus in response (breaks Terraform re-apply)
## Service

Lambda

## AWS API Action

`UpdateFunctionCode` + `GetFunction` (polling for completion)

## Expected behavior

After `UpdateFunctionCode`, the Terraform AWS provider polls `GetFunction` waiting for `LastUpdateStatus` to become `"Successful"`. Real AWS returns this field in `GetFunction` and `GetFunctionConfiguration` responses.

## Actual behavior

Floci's `GetFunction` response does not include `LastUpdateStatus` (or returns an empty string). Terraform's state waiter sees `""` instead of `"Successful"` and fails:

```
Error: updating Lambda Function (my-function) code: waiting for completion:
unexpected state '', wanted target 'Successful'. last error:
```

This only occurs on **re-apply** (updating an existing Lambda), not on initial creation.

## Reproduction

```bash
docker run -d -p 4566:4566 hectorvent/floci:1.5.3

# Create a Lambda
aws --endpoint-url http://localhost:4566 lambda create-function \
  --function-name test-func --runtime provided.al2 \
  --handler bootstrap --role arn:aws:iam::000000000000:role/test \
  --zip-file fileb://package.zip

# Update the code (simulating Terraform re-apply)
aws --endpoint-url http://localhost:4566 lambda update-function-code \
  --function-name test-func --zip-file fileb://package.zip

# Check GetFunction response
aws --endpoint-url http://localhost:4566 lambda get-function \
  --function-name test-func --query 'Configuration.LastUpdateStatus'
# → Returns null instead of "Successful"
```

### Terraform context

On second `terraform apply`, Terraform detects a code hash change and calls `UpdateFunctionCode`, then polls `GetFunction` for `LastUpdateStatus == "Successful"`.

## Impact

- First `terraform apply` succeeds (create path)
- Second `terraform apply` fails for all Lambda functions (update path)
- Affects any repo with Lambdas when running apply more than once

## Suggested fix

Include `LastUpdateStatus: "Successful"` and `LastUpdateStatusReason: "The function was successfully updated"` in `GetFunction` / `GetFunctionConfiguration` responses.

## Environment

- Floci: 1.5.3
- Terraform AWS provider: >= 5.17.0


Discussion:
Hi @diego-lambrechts-wp, thanks for taking the time to report this! 

We've seen it and will take a look. 

The Floci team




Patch:
diff --git a/src/main/java/io/github/hectorvent/floci/services/lambda/LambdaController.java b/src/main/java/io/github/hectorvent/floci/services/lambda/LambdaController.java
index 134ce835..d055ec61 100644
--- a/src/main/java/io/github/hectorvent/floci/services/lambda/LambdaController.java
+++ b/src/main/java/io/github/hectorvent/floci/services/lambda/LambdaController.java
@@ -479,6 +479,7 @@ private Map<String, Object> buildFunctionConfiguration(LambdaFunction fn) {
         node.put("LastModified", String.valueOf(fn.getLastModified()));
         node.put("RevisionId", fn.getRevisionId());
         node.put("Version", fn.getVersion());
+        node.put("LastUpdateStatus", "Successful");
 
         if (fn.getEnvironment() != null && !fn.getEnvironment().isEmpty()) {
             ObjectNode envNode = node.putObject("Environment");


Test patch:
diff --git a/src/test/java/io/github/hectorvent/floci/services/lambda/LambdaIntegrationTest.java b/src/test/java/io/github/hectorvent/floci/services/lambda/LambdaIntegrationTest.java
index dbd03d83..f76714f3 100644
--- a/src/test/java/io/github/hectorvent/floci/services/lambda/LambdaIntegrationTest.java
+++ b/src/test/java/io/github/hectorvent/floci/services/lambda/LambdaIntegrationTest.java
@@ -152,8 +152,21 @@ void createFunctionMissingRole_returns400() {
             .statusCode(400);
     }
 
+    // ── Issue #439: LastUpdateStatus in responses ─────────────────────
+
     @Test
     @Order(9)
+    void getFunctionIncludesLastUpdateStatus() {
+        given()
+        .when()
+            .get(BASE_PATH + "/functions/hello-world")
+        .then()
+            .statusCode(200)
+            .body("Configuration.LastUpdateStatus", equalTo("Successful"));
+    }
+
+    @Test
+    @Order(10)
     void deleteFunction() {
         given()
         .when()
@@ -163,7 +176,7 @@ void deleteFunction() {
     }
 
     @Test
-    @Order(10)
+    @Order(11)
     void deletedFunctionNotFound() {
         given()
         .when()
@@ -173,7 +186,7 @@ void deletedFunctionNotFound() {
     }
 
     @Test
-    @Order(11)
+    @Order(12)
     void createFunctionWithLargeInlineZip() throws Exception {
         // Build a valid zip with a handler file + 16 MB padding so the base64
         // encoding exceeds Jackson's former 20 MB maxStringLength default.