Skip to content

Bug: dateModify pipeline operations fail with type conversion error #3

@Stool233

Description

@Stool233

Bug Report: now | dateModify Pipeline Operations Fail with Type Conversion Error

Summary

The dateModify function fails when used in pipeline operations with the now function, causing a type conversion error. This affects the compatibility with standard Helm template functions.

Environment

  • GJSON Template Version: Latest (current main branch)
  • Go Version: 1.24.1
  • OS: macOS (Darwin 24.4.0)

Problem Description

When attempting to use now | dateModify "-1.5h" (a standard Helm template pattern), the template execution fails with the following error:

dateModify: reflect: Call using string as type time.Time

This suggests that the now function's return value is being incorrectly treated as a string type instead of time.Time when passed through the pipeline to dateModify.

Expected Behavior

The expression {{now | dateModify "-1.5h"}} should work the same way as in standard Go templates with Sprig functions, returning a time that is 1.5 hours earlier than the current time.

Actual Behavior

The template execution fails with a type conversion error, preventing the use of time modification operations in templates.

Steps to Reproduce

1. Create a simple test case

package main

import (
    "bytes"
    "fmt"
    template "github.com/higress-group/gjson_template"
)

func main() {
    tmpl, err := template.New("test").Parse("{{now | dateModify \"-1.5h\"}}")
    if err != nil {
        fmt.Printf("Parse error: %v\n", err)
        return
    }
    
    var buf bytes.Buffer
    err = tmpl.Execute(&buf, []byte(`{}`))
    if err != nil {
        fmt.Printf("Execute error: %v\n", err)
        return
    }
    
    fmt.Printf("Result: %s\n", buf.String())
}

2. Run the test

go run test.go

3. Observe the error

Execute error: template: test:1:19: executing "test" at <"-1.5h">: dateModify: reflect: Call using string as type time.Time

Root Cause Analysis

I conducted a systematic investigation to isolate the problem:

Test 1: Direct Sprig Function Testing ✅ PASSED

// Direct function calls work correctly
funcs := sprig.FuncMap()
nowFunc := funcs["now"].(func() time.Time)
dateModifyFunc := funcs["dateModify"].(func(string, time.Time) time.Time)

result := dateModifyFunc("-1.5h", nowFunc())
// Works perfectly - returns correct modified time

Test 2: Standard Go Template + Sprig ✅ PASSED

// Standard text/template with Sprig integration works correctly
tmpl := template.New("test").Funcs(sprig.TxtFuncMap())
tmpl.Parse("{{now | dateModify \"-1.5h\"}}")
// Executes successfully and returns correct result

Test 3: GJSON Template Library ❌ FAILED

// GJSON template fails with type conversion error
tmpl, _ := gjson_template.New("test").Parse("{{now | dateModify \"-1.5h\"}}")
tmpl.Execute(&buf, []byte(`{}`))
// Fails with: dateModify: reflect: Call using string as type time.Time

Detailed Test Results

Function Standard Go Template GJSON Template Status
{{now}} ✅ Works ✅ Works ✅ OK
{{now | date "2006-01-02"}} ✅ Works ✅ Works ✅ OK
{{dateModify "-1h" now}} ✅ Works ❌ Fails BUG
{{now | dateModify "-1h"}} ✅ Works ❌ Fails BUG
{{now | dateModify "-1h" | date "15:04"}} ✅ Works ❌ Fails BUG

Impact

This bug affects:

  • Working: Basic time functions (now, date)
  • Broken: Time modification operations (dateModify, date_modify)
  • Broken: Complex time pipeline operations
  • 🚨 Critical: Helm template compatibility for time operations

Suspected Cause

The issue appears to be in the pipeline type handling mechanism within the GJSON template library. When values are passed through pipelines, the type information for time.Time objects is not being preserved correctly, causing them to be treated as strings when they reach the dateModify function.

Workaround

Currently, there is no direct workaround within the template system. Time calculations must be performed in the application code before passing data to the template.

Additional Information

Error Details

  • The error occurs specifically when time.Time values are passed through pipelines
  • Both function call syntax and pipeline syntax fail
  • The now function itself returns the correct time.Time type
  • The issue is isolated to the GJSON template library's type handling

Test Files

The following test files demonstrate the issue:

  • Direct Sprig testing: Shows the underlying functions work correctly
  • Standard template testing: Shows the expected behavior
  • GJSON template testing: Reproduces the bug

Related

This issue may be related to other type conversion problems in pipeline operations, particularly with complex types from Sprig functions.

Request

Please investigate the pipeline type handling mechanism in the GJSON template library, specifically how time.Time and other complex types are preserved when passed between functions in pipeline operations.


Test Environment Details:

  • Sprig Version: v3.3.0
  • GJSON Version: v1.18.0
  • The issue is reproducible consistently across different time modification operations

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions